pull_request type, grant extensions, issue‑submission fix
Release history
markmhendrickson/neotoma releases
Deterministic state layer for AI agents. Stores versioned entities (contacts, tasks, transactions, decisions) with immutable observations, full provenance, and schema-first extraction. Local-first SQLite, cross-client memory across Claude, Cursor, ChatGPT, and OpenClaw. Website
All releases
34 shown
Tenant isolation + search improvements
Agent instructions + CLI changes + Plan entities
Reporter env required for submit_issue
- When upgrading from v0.10.x to v0.11.0, update any generated client code or scripts that reference `operations.storeStructured` to use `operations.store`.
- If your deployment relies on the removed `POST /store/unstructured` endpoint, refactor calls to send file‑only payloads via `POST /store` with appropriate fields (`file_content`, `mime_type`, or `file_path`).
- CLI users must replace `neotoma store-structured` and `neotoma store-unstructured` commands with `neotoma store` and the relevant flags.
- `POST /store` operationId changed from `storeStructured` to `store`. Codegen clients must reference `operations.store` instead of `operations.storeStructured`.
- `POST /store/unstructured` endpoint removed. File‑only writes now use `POST /store` with `file_content`, `mime_type`, or `file_path` fields.
- MCP tools `store_structured` and `store_unstructured` are no longer canonical; all storage must be performed via the unified `store` operation.
- Unified store operation (`POST /store`) supports structured entities, file‑backed sources, and combined payloads.
- Interpretation provenance added: store requests can include an `interpretation` block; new endpoints `POST /interpretations/create`, `list_interpretations` enable creating and listing interpretation runs.
- Inspector feedback admin workflow now includes CLI unlock flow, triage/sync panel, and short‑lived httpOnly cookies for secure sessions.
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.11.0 |
| Compare | v0.10.1 → v0.11.0 — view diff |
v0.11.0 is a release finalization for the unified store contract, interpretation provenance, MCP onboarding, Inspector feedback administration, and localized site expansion.
Highlights
- One canonical store surface. MCP and HTTP writes now use the unified
storeoperation for structured entities, file-backed sources, or both. Legacystore_structuredandstore_unstructuredreferences should move tostore. - Interpretation provenance is explicit. Store requests can include an
interpretationblock, and agents can create interpretation runs for existing sources withcreate_interpretation. - Lower-friction MCP setup for npm users.
neotoma mcp configdefaults to transport preset B, which uses local stdio for packaged installs and does not require a separate API process for the basic Cursor / Claude Code / Codex path. - Signed MCP proxy remains available. Presets A and D keep the signed HTTP
/mcpproxy path for AAuth attribution when the API is running. - Inspector feedback admin workflow. Maintainers can unlock feedback-admin sessions from the CLI and triage/sync feedback from the Inspector.
What changed for npm package users
CLI (neotoma, neotoma setup, neotoma mcp config, …)
neotoma setup --tool <tool> --yesremains the recommended greenfield command. It runs idempotent init, MCP config, CLI instruction setup, hooks/plugins where supported, and permission-file patches.neotoma mcp confignow defaults to transport preset B. Packaged npm installs launch Neotoma directly over stdio for local MCP clients; noneotoma api startis required for the default MCP path.--mcp-transport aremains available for signed AAuth HTTP/mcpproxy entries. Use it when the dev/prod API is already running and trusted attribution is more important than lowest setup friction.--mcp-transport dwrites signed prod-parity entries where both MCP slots point at prod HTTP/mcp.neotoma setupdocumentation now lists every setup flag, including--install-scope, permission--scope,--rewrite-neotoma-mcp,--skip-hooks,--all-harnesses,--dry-run, and--skip-permissions.neotoma processesadds a development/ops helper for listing and terminating Neotoma-related local processes.neotoma instructions printand/mcp-interaction-instructionsexpose the shipped MCP interaction instructions without requiring agents to inspect repo files.
Runtime / data layer
POST /storeis the canonical operation for structured and file-backed writes.POST /interpretations/createcreates interpretation rows for agent-extracted entities from an existing source.storerequests can includeinterpretationprovenance so observations link to both a source and interpretation run.- Registered user schemas take precedence over built-in aliases before store/interpretation routing falls back to code-defined aliases.
- Raw-fragment entity resolution prefers explicit
entity_id; source-only fragments resolve only when the source maps unambiguously to one entity.
MCP tools
- Added
create_interpretation. - Added
list_interpretations. - Removed canonical exposure of
store_structuredandstore_unstructured; usestore. - Deprecated store aliases still map to
storein internal contract mappings where compatibility is needed.
Inspector
- Added feedback admin unlock flow, including CLI challenge redemption and the Inspector
/feedback/admin-unlockpage. - Added feedback admin API client surfaces and a store-sync/repair panel for feedback mirrors.
Docs site and i18n
- Added layered locale packs for global chrome, home/body content, subpages, FAQ, docs hub, and CLI demo scenarios.
- Updated site examples to use
storeinstead ofstore_structured. - Regenerated static
site_pages/output is included in this release.
API surface & contracts
POST /storeoperationId is nowstore(wasstoreStructured).POST /store/unstructuredis removed. Send file-only or file+entity payloads toPOST /storeinstead.- Store request schemas include optional
interpretationprovenance. - Store responses may include
interpretation_idfor observations produced through an interpretation run. - Added schemas:
InterpretationConfig,StoreInterpretationInput,CreateInterpretationRequest, andCreateInterpretationResponse. - Added path:
POST /interpretations/create. listInterpretationsis now mapped as a CLI and MCP-backed operation.
Behavior changes
- First-time npm onboarding through MCP favors direct local stdio by default (
b) rather than signed HTTP proxy (a). - Users who want signed AAuth MCP attribution must explicitly choose
--mcp-transport aordand run a reachable HTTP API. - Site and agent-facing examples use
storeas the canonical tool name. - Existing stored data is not migrated.
Agent-facing instruction changes
- MCP and CLI instructions center the canonical
storetool. - Attachment/source-derived extraction guidance distinguishes ordinary chat-native stores from explicit interpretation provenance.
- Closing-store and display-rule requirements remain in force.
- Setup guidance points agents to
neotoma setup --tool <tool> --yesand the read-onlymcp guide/cli guidesurfaces instead of ad hoc shell introspection.
Plugin / hooks / SDK changes
- Cursor hook reminders and compliance detection now recognize canonical
storecalls and legacy store aliases. - Cursor hook follow-up behavior can be disabled with
NEOTOMA_HOOK_COMPLIANCE_PASSES=off. - Claude Code / Codex hook packages and docs are refreshed for the unified store wording and setup command names.
- Client turn-report helpers are updated for the same display and storage conventions.
Security hardening
- MCP proxy support enables stdio clients to send signed AAuth HTTP requests to
/mcpwhen using transport presets A or D. - Feedback admin sessions require hardware/software/operator-attested identity tiers and use short-lived httpOnly cookies.
- Protected agent capability examples now prefer
op: "store".
Docs site & CI / tooling
- Developer docs document MCP transport presets A-D with B as the npm-friendly default.
- CLI reference documents the full
neotoma setupflag surface and structured setup report. - README and install docs align on
neotoma setupas the default onboarding path. - Static site export includes the regenerated localized pages.
Internal changes
- MCP config generation routes entries through transport-aware builders.
- A local HTTP port file lets signed shims discover moved API ports after
pick-portchooses a non-default port. - Feedback admin session state is held in process memory; restarts require a new challenge.
- Inspector and root landing docs route through updated localized site data.
Fixes
- Fixed schema alias precedence so registered schemas win before built-in aliases such as
organization->company. - Fixed raw-fragment isolation when a source has observations for multiple entities.
- Fixed CLI MCP config naming for Claude Desktop
mcpsrv_*server IDs. - Fixed outdated site examples that taught
store_structured.
Tests and validation
npx tsc --noEmitnpx vitest run tests/contract/ --reporter=verbosenpx vitest run tests/cli/cli_command_coverage_guard.test.ts --reporter=verbosenpm run openapi:bc-diffnpm run build:servernpm pack --dry-run
Breaking changes
POST /storeoperationId changed fromstoreStructuredtostore. Codegen clients that referencedoperations.storeStructuredmust switch tooperations.store.POST /store/unstructuredwas removed. UsePOST /storewithfile_content+mime_typeorfile_pathfor file-only writes.- MCP tools
store_structuredandstore_unstructuredare no longer canonical. Agents and clients should callstore. - CLI commands
neotoma store-structuredandneotoma store-unstructuredare removed. Useneotoma storewith--entities,--file, or--file-path. - Default MCP transport changed from signed proxy preset A to local stdio preset B. Users who require signed HTTP
/mcpattribution must pass--mcp-transport aor--mcp-transport d.
Commits (v0.10.1 → v0.11.0)
9df225cchore: advance inspector for v0.11.053e238fchore: finalize v0.11.0 release
Full compare: v0.10.1...v0.11.0
Fixed regression that bypassed user‑registered entity schemas when an entity type overlapped a built‑in alias.
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.10.1 |
| Compare | v0.10.0 → v0.10.1 — view diff |
This hotfix preserves user-registered entity schemas when their type name overlaps a built-in alias.
Highlights
- Keep custom schemas authoritative.
store_structuredand interpretation now check active DB-registered schemas before applying built-in aliases such asorganization->company.
What changed for npm package users
CLI (neotoma, neotoma api start, …)
- No CLI command surface changes.
- CLI-backed writes that reach the shared store path inherit the schema-routing fix when they submit records with a user-registered
entity_type.
Runtime / data layer
- Structured storage now loads the active schema for the submitted
entity_typebefore applying code-defined aliases. A user-registeredorganizationschema therefore validates asorganizationinstead of being remapped to the built-incompanyschema. - Interpretation applies the same precedence rule, so extracted entities respect registered schemas before alias fallback.
Shipped artifacts
- Runtime package contents change only through the patched server and interpretation code.
- No OpenAPI, MCP tool definition, CLI command, or package export changes are included in this hotfix.
API surface & contracts
- No OpenAPI schema changes.
- No MCP tool additions, removals, or request/response shape changes.
- The observable contract for existing
store_structuredcallers is compatibility-preserving: registered schemas now win over built-in aliases when both could match.
Behavior changes
- Submitting
entity_type: "organization"now uses an active user/globalorganizationschema when one exists. - The built-in
companyalias fororganizationremains available as a fallback for users who have not registered a separateorganizationschema. - Existing stored entities are not migrated or rewritten by this release.
Agent-facing instruction changes (ship to every client)
- No agent-facing instruction changes are included in this hotfix.
Plugin / hooks / SDK changes
- No plugin, hook, SDK, or client package changes.
Security hardening
- No security-surface changes.
Docs site & CI / tooling
- No docs site or CI changes are included in this hotfix.
Internal changes
- Store-path type routing now checks
schemaRegistry.loadActiveSchema(entityType, userId)beforeresolveEntityTypeFromAlias(entityType). - Interpretation type routing skips alias resolution when the extracted type already exists in the active schema registry.
Fixes
- Fixed a regression where a user-registered
organizationschema could be bypassed because the built-incompanyschema declaresorganizationas an alias. The regression caused fields outside the built-incompanyschema, such asslug,sector,location, and custom relationship fields, to land inraw_fragments.
Tests and validation
npx vitest run tests/services/schema_definitions.test.ts --reporter=verbosenpx vitest run tests/services/entity_resolution.test.ts --reporter=verbosenpx vitest run tests/integration/store_registered_schema_alias_precedence.test.ts --reporter=verbosenpx vitest run tests/contract/ --reporter=verbose
Breaking changes
No breaking changes.
Commits (v0.10.0 → v0.10.1)
8789b9dMerge branch 'hotfix/v0.10.1'107dc91Bump version to v0.10.195cc8befix(store): preserve registered schema type precedence63022f3docs(site): smooth agent storage guidance copy7046532docs(site): clarify storage guidance and API startupc7f9af6docs(release): move v0.10.0 GitHub supplement to completed
Full compare: v0.10.0...v0.10.1
- `validateTokenAndGetConnectionId` now returns `tokenRefreshFailed` for expired tokens; update client error handling to invoke the new `refresh_token` endpoint.
- The OpenCode plugin adopts the v2 hook API while retaining legacy aliases for backward compatibility.
- Access tokens that have passed their `access_token_expires_at` are now rejected by `validateTokenAndGetConnectionId`; clients must handle the `tokenRefreshFailed` error and refresh via the new `refresh_token` grant type.
- Token expiry enforcement prevents use of expired access tokens that previously passed validation.
- `POST /oauth/token` supports `grant_type=refresh_token` to obtain fresh access tokens without re‑authorizing.
- New integration pages `/neotoma-with-opencode` and `/neotoma-with-ironclaw` with SEO metadata, routing, and brand icons.
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.10.0 |
| Compare | v0.9.1 → v0.10.0 — view diff |
MCP OAuth connections now support refresh tokens, the docs site adds OpenCode and IronClaw integration guides plus three new operational guides, and the OpenCode plugin adopts the v2 hook API with backward-compatible legacy aliases.
Highlights
- MCP clients stay connected without re-auth. The
/oauth/tokenendpoint now acceptsgrant_type=refresh_token, and themcp_oauthservice transparently refreshes expired access tokens against the upstream provider. Local-backend connections mint a fresh local token on refresh. - Connect OpenCode and IronClaw to Neotoma. New integration landing pages (
/neotoma-with-opencode,/neotoma-with-ironclaw) with SEO metadata, routing, and brand icons join the docs site alongside the existing Claude, Cursor, Codex, and OpenClaw guides. - Three new operational guides on the docs site.
/what-to-store(tiered entity guidance),/backup(SQLite + source protection), and/tunnel(HTTPS tunnels for remote MCP clients) fill common first-week questions. - OpenCode plugin speaks the v2 hook API.
event(),tool.execute.after, andexperimental.session.compactingare now the primary entry points; legacy aliases (session.started,message.user,tool.called,chat.compacted,message.assistant) remain for older OpenCode builds.
What changed for npm package users
CLI (neotoma, neotoma api start, …)
- No CLI command changes in this release.
Runtime / data layer
POST /oauth/tokennow acceptsgrant_type=refresh_tokenalongsideauthorization_code. A validrefresh_tokenreturns a freshaccess_token(and optionally a rotatedrefresh_token) without requiring the user to re-authorize through the browser flow.getAccessTokenForConnectionrefreshes against the upstream auth provider when a stored access token expires, persisting the new token and (if rotated) the new refresh token inmcp_oauth_connections.validateTokenAndGetConnectionIdnow checksaccess_token_expires_atand returns atokenRefreshFailederror for expired tokens instead of silently succeeding. Both local-backend and remote-backend paths enforce this check.- New
refreshAccessTokenexport handles the full refresh cycle: find connection by refresh token, exchange with the provider (or mint locally), persist, and return the RFC 6749 token response shape.
Shipped artifacts
openapi.yaml— unchanged in the working tree (committed changes in v0.9.1 already shipped the expanded schema).dist/— rebuilt with refresh-token paths.
API surface & contracts
POST /oauth/token: newrefresh_tokengrant type. Request body:{ grant_type: "refresh_token", refresh_token: "<token>" }. Response shape:{ access_token, token_type, expires_in, refresh_token?, scope? }.- No other REST or MCP tool surface changes.
Behavior changes
- Token expiry enforcement:
validateTokenAndGetConnectionIdnow rejects expired access tokens instead of returning them. MCP clients that previously relied on a stale token will receive an error prompting refresh. This is a correctness fix, not a breaking change — the prior behavior was silently returning invalid credentials. - Site navigation reordered: Integration items are now alphabetical (ChatGPT, Claude, Claude Code, Codex, Cursor, IronClaw, OpenClaw, OpenCode). "Connect a remote Neotoma" renamed to "Connect remotely". "Expose tunnel" and "What to store first" added to the Getting Started nav group.
Agent-facing instruction changes
- Agent instruction sync rules, conversation turn docs, and agentic eval subsystem docs were updated in the committed
36efc6e3. No net-new instruction blocks in the working-tree delta. .claude/and.cursor/rules refreshed: newcheckpoint_management,post_build_testing,release_detection,release_status_readme_updaterules;image_generationandprocess_feedbackskill removed;publishskill added;create_releaseandreleaseskills updated for the v0.10.0 workflow.
Plugin / hooks / SDK changes
@neotoma/opencode-plugin
- Adopts the OpenCode v2 hook API:
event()dispatchessession.created,session.compacted, andmessage.updatedevents;tool.execute.afterreplacestool.called;experimental.session.compactinginjects the compact Neotoma turn checklist. - Legacy hooks (
session.started,message.user,tool.called,chat.compacted,message.assistant) remain as aliases so existing OpenCode builds continue to work. message.userhook now stores aconversationentity alongside the userconversation_messagein a single store call with an inlinePART_OFrelationship, matching the canonical store recipe.- New
NeotomaClientLikeinterface andclientoption enable test-seam injection without a live server. cwdoption andNEOTOMA_HOOK_STATE_DIRenv var for explicit provenance and hook-state directory overrides.- Determinism fix:
Date.now()fallbacks in idempotency keys and session IDs replaced with stable"unknown"sentinel values. package.jsongainskeywords,author,repository,homepage, andbugsfields for npm discoverability.- README rewritten with npm-package install path (
"plugin": ["@neotoma/opencode-plugin"]inopencode.json),export const Neotoma = neotoma()pattern, and updated event table.
Security hardening
- Token expiry is now enforced on read (both local and remote paths), preventing use of expired access tokens that previously passed validation.
Docs site & CI / tooling
- New pages:
/what-to-store(What to store first),/backup(Backup and restore),/tunnel(Expose tunnel),/neotoma-with-opencode(OpenCode integration),/neotoma-with-ironclaw(IronClaw integration). - New icons:
IronClawIconandOpenCodeIconSVG components. - SEO: Route metadata entries for all five new pages with title, description, breadcrumb, and keywords.
- Navigation: Site nav categories updated — integrations listed alphabetically, Getting Started expanded with What to Store, Backup, and Tunnel entries.
- Localized site pages: All 12 language variants regenerated (~3,174 files) reflecting the new pages and nav changes.
- IronClaw MCP setup guide:
docs/developer/mcp_ironclaw_setup.mdadded. - OpenCode hooks doc: Updated event table and install instructions to match v2 plugin API.
- Docs reorganization: MVP planning docs (
FUNCTIONAL_REQUIREMENTS.md,MANIFEST_ALIGNMENT_SUMMARY.md,MVP_EXECUTION_PLAN.md,MVP_FEATURE_UNITS.md,MVP_OVERVIEW.md) moved fromdocs/specs/todocs/releases/archived/mvp_planning/.
Internal changes
- Foundation submodule updated from
14442cbdtof3c5c53(store-neotoma skill, plan_sections_rules, draft-illustration skill, release workflow refinements). .claude/rules and skills synced with foundation: rules modernized,setup_symlinksskill removed in favor ofsetup_cursor_copies,publishskill added..cursor/skills synced:create-releaseanddraft-illustrationupdated with style references.- Various docs refreshed: ICP profiles, estimation methodology, readme generation framework, development workflow, MCP overview, observation architecture docs, creating feature units, multi-agent orchestration, worker agent template.
- Aspirational release plans for v0.9.0 and v1.0.0 updated.
LifecycleDemoStrip,SitePageHome2, andWhoProfileCardVisualfrontend components added/updated (committed in36efc6e3).conversation/v1.3.jsonschema snapshot added.
Fixes
- Expired token passthrough:
validateTokenAndGetConnectionIdpreviously returned connection info for expired access tokens without checkingaccess_token_expires_at. Both local-backend and remote paths now reject expired tokens with a clear error. - OpenCode plugin determinism: Replaced
Date.now()fallbacks in idempotency keys with stable sentinel values, preventing nondeterministic entity resolution. - OpenCode plugin orphaned messages: User messages are now stored with an inline
PART_OFrelationship to the conversation entity in a single store call, preventing orphanedconversation_messageentities.
Tests and validation
tests/integration/mcp_oauth_token_endpoint.test.ts— integration tests for therefresh_tokengrant type on the/oauth/tokenendpoint.tests/unit/opencode_plugin.test.ts— unit tests for the OpenCode plugin v2 hook API and legacy alias dispatch.tests/contract/ironclaw_integration.test.ts— contract tests for IronClaw MCP integration.
Breaking changes
- Token expiry enforcement: Access tokens that have passed their
access_token_expires_atare now rejected byvalidateTokenAndGetConnectionId. Previously these would silently succeed. MCP clients should handle thetokenRefreshFailederror by refreshing via the newrefresh_tokengrant type. This is a correctness fix — the prior behavior was a bug. - Ship constraint:
docs/private/is untracked and excluded from this release per security policy. Foundation submodule dirty edits (release skill and workflow) will be committed inside the submodule before tagging.
Commits (v0.9.1 → v0.10.0)
5c8e7d0Merge dev into main for v0.10.06c2fd50Bump version to v0.10.039a5f9dPre-release: include pending changes for v0.10.036efc6efeat(agent): add compliance eval and hook enforcement updates
Full compare: v0.9.1...v0.10.0
Claude Desktop compatibility fixed by updating MCP config keys and URI scheme for the timeline widget.
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.9.1 |
| Compare | v0.9.0 → v0.9.1 — view diff |
v0.9.1 is a narrow Claude Desktop MCP compatibility hotfix for local Neotoma MCP installs.
Highlights
- Claude Desktop can accept Neotoma's generated MCP server entries.
neotoma mcp checknow usesmcpsrv_neotoma_devandmcpsrv_neotomainclaude_desktop_config.json, matching Claude Desktop's server ID validation. - Embedded MCP UI metadata uses the standard Apps URI scheme. The timeline widget is now advertised as
ui://neotoma/timeline_widgetwhile the server still accepts the legacyneotoma://ui/timeline_widgetURI for compatibility.
What changed for npm package users
CLI (neotoma mcp check)
- Claude Desktop config installs now write
mcpsrv_neotoma_devandmcpsrv_neotomakeys instead ofneotoma-devandneotoma. - Existing Claude Desktop configs that still use
neotoma-devorneotomaare reported as repairable issues, and the fixer migrates those keys to the compliantmcpsrv_*IDs. neotoma uninstallrecognizes the new Claude Desktopmcpsrv_neotoma*IDs when removing Neotoma MCP entries.
Runtime / data layer
- No storage, reducer, schema, or database behavior changed.
Shipped artifacts
dist/output should include the new MCP Apps UI URI afternpm run build:server.
API surface & contracts
- OpenAPI is unchanged.
- MCP tool schemas are unchanged.
- The MCP resource list and static server card now advertise the timeline widget resource as
ui://neotoma/timeline_widget. - The MCP server continues to parse
neotoma://ui/timeline_widgetso older clients do not break.
Behavior changes
- Claude Desktop users should no longer see server-ID validation failures caused by
neotomaorneotoma-devkeys in generated MCP config. - MCP Apps clients that expect
ui://<server>/<resource>resource URIs now receive a compliant timeline widget URI.
Docs site & CI / tooling
- Claude Desktop setup documentation now shows the
mcpsrv_*keys and explains why they are required. - ChatGPT Apps validation references now use
ui://neotoma/timeline_widget.
Internal changes
- Added focused tests for static server card UI metadata, MCP resource URI parsing, and Claude Desktop MCP config migration.
Fixes
- Fixed Claude Desktop compatibility with generated local Neotoma MCP server IDs.
- Fixed MCP Apps UI resource URI advertising for the timeline widget.
Tests and validation
- Focused validation should include:
npx vitest run tests/unit/mcp_server_card.test.ts tests/unit/mcp_resource_uri.test.ts tests/cli/cli_mcp_commands.test.tsnpm run type-checknpm run build:servernpm run openapi:bc-diffnpm pack --dry-run
Breaking changes
No breaking changes.
Commits (v0.9.0 → v0.9.1)
3614facfix(mcp): Claude Desktop mcpsrv_* IDs and ui:// timeline widgetf8d67aafix(ci): unblock GitHub Pages deploy and CI after v0.9.0
Full compare: v0.9.0...v0.9.1
- Bundled Inspector SPA at /inspector
- Per-turn conversation_turn telemetry from all hook harnesses
- Local feedback pipeline without hosted config
Full changelog
[email protected] release-notes:render
tsx scripts/render_github_release_notes.ts --tag v0.9.0 --supplement docs/releases/in_progress/v0.9.0/github_release_supplement.md
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.9.0 |
| Compare | v0.8.0 → v0.9.0 — view diff |
v0.9.0 delivers the bundled Inspector, a unified turn-telemetry pipeline across all hook harnesses, the self-contained local feedback pipeline, and sandbox ephemeral sessions — all aimed at making a fresh npm install -g neotoma immediately useful without external configuration.
Highlights
- Inspector ships inside the npm package.
neotoma api startnow serves the Inspector SPA at/inspectorout of the box — no separate build, noNEOTOMA_INSPECTOR_STATIC_DIR, no Docker flag. Operators can disable, relocate, or point at an external Inspector via six newNEOTOMA_INSPECTOR_*env vars. - Every hook harness reports per-turn telemetry to a single
conversation_turnentity. cursor-hooks, opencode-plugin, claude-code-plugin, codex-hooks, and claude-agent-sdk-adapter all accrete onto oneconversation_turnkeyed by(session_id, turn_id), capturing hook events, tool counts, missed steps, compliance status, and — on skipped-store turns — a root-cause classification with recommended repairs. The legacyturn_complianceentity is preserved as an alias. - Run the full feedback pipeline locally with zero hosted config.
submit_feedbacknow mirrors every submission into aneotoma_feedbackentity in the local DB. Inspector/feedback,neotoma triage, and the ingest cron all work end-to-end on a fresh install. SetNEOTOMA_FEEDBACK_ADMIN_MODE=disabledto force read-only. - Sandbox visitors get ephemeral per-session isolation. Cookie-based sessions with one-time-code redemption, per-pack seed data, automatic sweep, and full data purge on session end replace the single shared
SANDBOX_PUBLIC_USER_ID. - Docs site restructured for scannability. Large monolithic pages (Install, Agent Instructions, Evaluate, AAuth Reference) split into focused sub-pages; "Verticals" renamed to "Use Cases" with a new landing shell.
What changed for npm package users
CLI (neotoma, neotoma api start, …)
neotoma api startnow serves the Inspector at/inspectorby default. The bundled SPA is baked intodist/inspector/at publish time viaprepublishOnly. No env vars required for the default path.neotoma triage --set-statusand--resolvenow mirror triage changes onto theneotoma_feedbackentity viamirrorLocalFeedbackToEntity, keeping the JSON store and entity graph in sync.tsc --watch --preserveWatchOutputreplaces baretsc --watchin all watch/dev scripts and the CLI's internalapi startspawner, eliminating the terminal-clearing behavior that made concurrent output unreadable.
Runtime / data layer
- New
inspector_mount.tsservice handles the Inspector SPA lifecycle: bundled-first (fromdist/inspector/), fallback toNEOTOMA_INSPECTOR_STATIC_DIR, or external URL viaNEOTOMA_PUBLIC_INSPECTOR_URL. Live-build mode (NEOTOMA_INSPECTOR_LIVE_BUILD=1) re-readsindex.htmlon each request and injects a 2-second poll for watch workflows. cookie-parseradded as a runtime dependency for sandbox session management.sandbox_sessionstable added to SQLite schema with bearer-token-hash, one-time-code-hash, pack selection, and expiry tracking.local_auth_usersgainsis_ephemeralcolumn for session-scoped users.- New
conversation_turnseeded schema (160 lines) inschema_definitions.tswith aliasesturn_complianceandturn_activity, composite canonical-name identity[session_id, turn_id], andrejectcollision policy. Includesinstruction_diagnostics(classification, confidence, reason, signals, recommended_repairs) andfollowup_messagefields for compliance diagnosis. - New
listConversationTurnsandgetConversationTurnservice functions. listRecentConversationsservice updated.MCP_INTERACTION_INSTRUCTIONS_FALLBACKconstant exported fromserver.ts— a compact-mode fallback aligned to the critical [TURN LIFECYCLE] / [STORE RECIPES] / [COMMUNICATION & DISPLAY] / [ERRORS & RECOVERY] invariants, replacing the old unstructured inline fallback.- Feedback admin proxy (
admin_proxy.ts) reworked for tri-state mode resolution (hosted/local/disabled) withNEOTOMA_FEEDBACK_ADMIN_MODEenv var.GET /admin/feedback/preflightnow returnsmodeandmode_env. Local-mode routes read/write the JSON store and mirror to entity graph. mirrorLocalFeedbackToEntity(src/services/feedback/mirror_local_to_entity.ts) andstoredFeedbackToEntityprojection (src/services/feedback/neotoma_payload.ts) extracted as canonical helpers used by submit, ingest cron, CLI triage, and admin proxy.
Shipped artifacts
dist/inspector/is now included in the npm packagefileslist. The Inspector SPA is built duringprepublishOnly.openapi.yaml—neotoma_envfield added to the/mcp/configresponse schema.
API surface & contracts
GET /admin/feedback/preflightresponse now includesmode: "hosted" | "local" | "disabled"andmode_env: "NEOTOMA_FEEDBACK_ADMIN_MODE"alongside the existingconfiguredboolean.GET /admin/feedback/pendinginlocalmode returns records fromLocalFeedbackStorewithmode: "local"in the response body.POST /admin/feedback/:id/statusinlocalmode writes the JSON record and mirrors toneotoma_feedbackentity. All admin routes still requirehardware/software/operator_attestedAAuth tier.GET /mcp/configresponse now includesneotoma_env(resolvedNEOTOMA_ENVfor the running process).- Sandbox session endpoints:
POST /sandbox/session/new,POST /sandbox/session/redeem,GET /sandbox/session,DELETE /sandbox/session.
Behavior changes
- The Inspector is served at
/inspectorby default on everyneotoma api start. The root landing page links to it. Previously requiredNEOTOMA_INSPECTOR_STATIC_DIRand a separate build step. - Unconfigured feedback installs default to
localmode instead of returning501 admin_proxy_unconfigured. The 501 is now reserved forNEOTOMA_FEEDBACK_ADMIN_MODE=disabled. - Sandbox mode uses ephemeral per-visitor sessions instead of a single shared
SANDBOX_PUBLIC_USER_ID. Each visitor gets isolated data seeded from a fixture pack. watch:fullandwatch:full:prodnow include a concurrent Inspector watcher with live-build mode, plus adev:resources:watchlane showing local resource URLs.pack:localnow includesbuild:inspectorso local pack testing includes the Inspector.- GitHub Pages site build fixes root-absolute asset paths (
/assets/…) instead of relative paths, fixing broken chunk URLs on nested pages.
Agent-facing instruction changes
MCP_INTERACTION_INSTRUCTIONS_FALLBACKis a compact, structured fallback covering the critical turn lifecycle, store recipes, display rule, and retry policy. Agents connecting to a Neotoma server wheredocs/developer/mcp/instructions.mdis unreadable (packaged app, broken path) receive this compact block instead of the old unstructured fallback. The compact block is tested bytests/unit/mcp_instructions_fallback_invariants.test.ts.
Plugin / hooks / SDK changes
All five harness packages received a coordinated rewrite to share the same turn-telemetry and failure-signal architecture:
cursor-hooks (TypeScript, +1,624 lines)
- New
session_start.tshook: initializes per-turn state, optionally injects compact reminder for small models, seeds recent timeline retrievals. before_submit_prompt.ts: user message capture and identifier-retrieval warmup. (Cursor dropsadditional_contextfrom this hook; reminders usesessionStartandpostToolUseinstead.)- New
post_tool_use_failure.ts: capturestool_invocation_failureentities for Neotoma-relevant tools, bumps per-(tool, error_class)counter on disk. after_tool_use.ts(renamed frompostToolUsein docs):tool_invocationobservation, optional small-model reminder, failure-hint surfacing.stop.ts:conversation_messagesafety net, compliance backfill with bounded root-cause classification (instruction_diagnostics,diagnosis_confidence,recommended_repairs), classifier-drivenfollowup_messagefor non-compliant turns._common.ts: per-turn state management (NEOTOMA_HOOK_STATE_DIR), failure-signal accumulator with PII scrub, error classification, small-model detection,isExpectedNetworkErrordowngrade,ConversationTurnObservationInputtype,accreteTurnhelper.- 12+ new env vars:
NEOTOMA_HOOK_STATE_DIR,NEOTOMA_HOOK_FEEDBACK_HINT,NEOTOMA_HOOK_FEEDBACK_HINT_THRESHOLD,NEOTOMA_HOOK_COMPLIANCE_FOLLOWUP,NEOTOMA_HOOK_SMALL_MODEL_PATTERNS,NEOTOMA_HOOK_SMALL_MODEL_DETECTED,NEOTOMA_HOOK_DETECTED_MODEL,NEOTOMA_LOCAL_BUILD,NEOTOMA_HOOK_CONNECTION_ID.
opencode-plugin (TypeScript, +626 lines)
- Same
isNeotomaRelevantTool/scrubErrorMessage/classifyErrorMessage/ failure-counter infrastructure. - Per-turn
conversation_turnaccretion viarecordConversationTurnfrom@neotoma/client. - Failure-hint surfacing not available (opencode has no prompt-injection channel); storage-only capture.
claude-code-plugin (Python, +354 lines in _common.py)
- Shared
is_neotoma_relevant_tool(),scrub_error_message(),classify_error_message(), per-session failure counter with 24h TTL. tool_invocation_failureentity storage. One-shot hint viauser_prompt_submitadditional context.- All hook entry points (
post_tool_use,user_prompt_submit,session_start,stop) updated for turn telemetry.
codex-hooks (Python, +264 lines in _common.py)
- Same Python failure-signal infrastructure. Storage-only (no prompt-injection channel).
notifyandsession_endhooks updated for turn telemetry.
claude-agent-sdk-adapter (TypeScript, +372 lines)
- Same TS failure-signal infrastructure.
recordConversationTurnfrom@neotoma/client. UserPromptSubmithook surfaces one-shot failure hint.
@neotoma/client
- New
helpers.tsexports:ConversationTurnInputinterface andrecordConversationTurnhelper for harness-agnostic turn telemetry writes.
Docs site & CI / tooling
- Frontend restructuring: Large monolithic pages split into focused sub-pages —
AgentInstructionsDisplayPage,AgentInstructionsRetrievalPage,AgentInstructionsStoreRecipesPage,EvaluateAgentInstructionsPage,InstallDockerPage,InstallManualPage. NewInstallCodeBlockcomponent. - "Verticals" → "Use Cases":
VerticalsIndexPage/VerticalIconTile/VerticalLandingShelldeleted; replaced byUseCasesIndexPage/UseCaseIconTile/UseCaseLandingShell. - GitHub Pages build: Asset paths normalized to root-absolute
/assets/…everywhere (fixes broken chunk URLs on nested routes). NewfinalizeBundledAssetPathsInAllHtmlpass andvalidate_site_export.tschecks. pick-port.js: New--print-resourcesflag displays local resource URLs (Inspector, MCP, API, UI) alongside port allocation.show-dev-resources.js: New script (anddev:resources/dev:resources:watchnpm scripts) that prints a summary of local dev resource URLs.watch:full/watch:full:prod: Now include Inspector watcher (watch:inspector) anddev:resources:watchas concurrent lanes;NEOTOMA_INSPECTOR_LIVE_BUILD=1set automatically.- New
eval:tier1/eval:tier1:update: npm scripts for the Tier 1 agentic eval harness. --preserveWatchOutputadded to alltsc --watchinvocations across npm scripts and CLI internals.
Internal changes
cookie-parserdependency added for sandbox session cookie handling.- Dockerfile simplified: Inspector is always built (no
BUILD_INSPECTORarg), served at/inspectorfromdist/inspector/.VITE_NEOTOMA_API_URLandVITE_PUBLIC_BASE_PATHbuild args removed. fly.sandbox.tomlcleaned up:BUILD_INSPECTOR,VITE_NEOTOMA_API_URL,VITE_PUBLIC_BASE_PATH,NEOTOMA_INSPECTOR_STATIC_DIR,NEOTOMA_INSPECTOR_BASE_PATHremoved.- Sandbox deployment docs (
docs/subsystems/sandbox_deployment.md) substantially rewritten for ephemeral sessions, pack registry, and updated architecture diagram. - Hook integration docs (
docs/integrations/hooks/) rewritten with expanded configuration tables, failure-signal accumulator documentation, and instruction diagnostics section. - Feedback pipeline docs (
docs/subsystems/agent_feedback_pipeline.md) expanded with signal sources section, local pipeline mode docs, and Inspector admin proxy tri-state mode. - Schema snapshots README updated.
src/services/root_landing/updated:readNeotomaConfigEnvironment,parseCookieBearer, sandbox pack registry integration, Inspector URL resolution viainspector_mount.ts.- New sandbox service files:
pack_registry.ts,seeder.ts,sessions.tsundersrc/services/sandbox/.
Fixes
- GitHub Pages nested-route asset paths fixed (root-absolute
/assets/…instead of relative../assets/). tsc --watchterminal clearing eliminated across all dev workflows via--preserveWatchOutput.- Feedback admin proxy no longer returns
501on unconfigured installs; defaults tolocalmode.
Tests and validation
tests/integration/feedback_admin_proxy.test.ts— extended with tri-state mode resolver, preflightmode/mode_envfields, and uniform tier-gate verification across hosted/local/disabled modes.tests/integration/root_landing.test.ts— new (+91 lines), covers landing page context, mode resolution, and Inspector URL integration.tests/services/schema_definitions.test.ts— new (+41 lines), validates seeded schema definitions including the newconversation_turnschema.
Breaking changes
No breaking changes. The OpenAPI addition (neotoma_env on /mcp/config) is additive. The old NEOTOMA_INSPECTOR_STATIC_DIR / NEOTOMA_INSPECTOR_BASE_PATH env vars continue to work as overrides. The turn_compliance entity type is preserved as an alias of conversation_turn.
Commits (v0.8.0 → v0.9.0)
3f24c4dBump version to 0.9.0de411eePre-release: include pending changes for v0.9.0b0e7c19fix(ci): unblock v0.8.0 GitHub Pages deploy
Full compare: v0.8.0...v0.9.0
- NEOTOMA_AGENT_CAPABILITIES_* env vars removed; migrate with 'neotoma agents grants import'
- agent_grant entity type replaces committed agent_capabilities.default.json
- Hardware attestation verification (Apple Secure Enclave, WebAuthn-packed, TPM 2.0)
- Attestation revocation lookup (OCSP, CRL) prevents revoked agents from writing
- Hardware attestation on macOS, Linux, Windows, YubiKey
- Four-tier attribution cascade (anonymous, software, operator_attested, hardware)
- Attestation revocation enforcement by default
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.8.0 |
| Compare | v0.7.1 → v0.8.0 — view diff |
v0.8.0 makes attribution tiers honest, ships hardware attestation end-to-end on macOS, Linux, Windows, and YubiKey, replaces the env-driven agent capability registry with a managed agent_grant entity type, promotes AAuth from a Sandbox-only auth path to a first-class auth method on every deployment, and gives the Inspector a real surface for the new attestation and admission diagnostics. This release consolidates work originally planned for v0.8.0 through v0.12.0 — the four-tier cascade, three real attestation verifiers (Apple Secure Enclave, WebAuthn-packed, TPM 2.0), four CLI hardware backends (Apple SE, libtss2, Windows TBS+CNG, YubiKey via libykcs11), attestation revocation lookup in enforce mode by default — into one cut.
Highlights
hardwaretier now means hardware, on every supported platform. Algorithm-only promotion is gone. Thehardwaretier requires a verifiedcnf.attestationenvelope cryptographically bound to the signing key, and the CLI can now mint that envelope on macOS (Secure Enclave), Linux (TPM 2.0 via libtss2), Windows (TBS + CNG), and YubiKey 5 / 5C / Bio (libykcs11) — three attestation formats (apple-secure-enclave,webauthn-packed,tpm2), one consistent server-side verification contract.- Per-agent capability scoping is now data, not env. The
NEOTOMA_AGENT_CAPABILITIES_*env vars and the committedconfig/agent_capabilities.default.jsonregistry are removed in favour ofagent_grantentities managed in the Inspector under "Agents → Agent grants" or via standard MCP / REST entity-store calls. A newneotoma agents grants import --owner-user-id <usr_…>command migrates legacy registries idempotently. Setting any of the removed env vars now causes startup to fail with a structured error pointing at the upgrade command. - New
operator_attestedtier betweensoftwareandhardware. Verified-AAuth callers whoseiss,sub, oriss::subpair appears on the operator allowlist are surfaced asoperator_attested(rank 3). Configured viaNEOTOMA_OPERATOR_ATTESTED_ISSUERSandNEOTOMA_OPERATOR_ATTESTED_SUBS. Trusted-operator agents are now distinguishable from generic software agents without overstating cryptographic guarantees. - Attestation revocation enforced by default. Apple's anonymous-attestation revocation endpoint, OCSP for
webauthn-packedleaves, and OCSP / CRL fortpm2AIK chains now demote revoked agents fromhardware(oroperator_attested) tosoftwarewithfailure_reason: "revoked". Operators that need an audit window can opt in toNEOTOMA_AAUTH_REVOCATION_MODE=log_onlyordisabled. Fail-open on responder outage is the default. - Inspector rewritten around the four-tier cascade. The new
/inspector/*and/aauth/*route sets render the attestation envelope chain, AAGUID admission, revocation status, operator allowlist source, and per-agent grant lifecycle inline — the prior tier-badge-only presentation is replaced with a tier badge whose tooltip and detail panel name exactly why a tier resolved the way it did. - AAuth is now a first-class auth path beyond Sandbox. In v0.7.1, AAuth-verified writes only resolved to a real
user_idinsideisSandboxMode()(viaensureSandboxAauthUser), and the only AAuth-required write route (/sandbox/aauth-only/store) was sandbox-only. Outside Sandbox, AAuth was attribution-decoration on top of Bearer/OAuth/Ed25519. v0.8.0 promotes the AAuth →agent_grantadmission path to a first-class auth method on every deployment: a verified AAuth signature whose identity (thumbprint>(sub, iss)>sub) matches an active grant resolves to that grant's owner user_id and reaches the same write surface as a Bearer token (/store,/observations/create,/create_relationship,/correct, MCP, …) — no Bearer required. The same hardware attestation, four-tier cascade, operator allowlist, and revocation enforcement that previously decorated tiers in Sandbox now gate writes on production deployments through theassertCanWriteProtectedguard. Sandbox-mode partitioning continues unchanged for anonymous callers; the admission path coexists with it.
Ship constraints
- Attribution tiers are resolved by an explicit cascade in
src/middleware/aauth_verify.ts. Algorithm choice no longer influences the tier — only verified attestation, operator allowlist match, and signature validity. - One additive schema change: a new
agent_grantentity type is registered insrc/services/schema_definitions.ts. No table migration is required (the entity is stored in the existing entity / observation infrastructure). The legacyattribution_tiercolumn accepts the newoperator_attestedvalue; existing rows are not rewritten. - Hardware attestation native bindings ship as
optionalDependencies:@neotoma/aauth-mac-se(darwin),@neotoma/aauth-tpm2(Linux + libtss2),@neotoma/aauth-win-tbs(Windows + TBS),@neotoma/aauth-yubikey(cross-platform + libykcs11). Hosts without the matching toolchain or hardware fall back to the software signer with no behavioural change beyond the tier rename. - Bundled trust roots are committed at
config/aauth/:apple_attestation_root.pem(Apple App Attestation Root CA) andtpm_attestation_roots/(Infineon, STMicro, Intel, AMD bundles, each with sourcing notes and SHA-256 fingerprints). Operators can supplement or replace either set viaNEOTOMA_AAUTH_ATTESTATION_CA_PATH. - Revocation is
enforceby default. Operators that want to audit before flipping should setNEOTOMA_AAUTH_REVOCATION_MODE=log_onlyahead of upgrading, observeattribution_decisionlog lines forrevocation.status: "revoked"withrevocation.demoted: false, and only then drop the override. - The
NEOTOMA_AGENT_CAPABILITIES_*env vars andconfig/agent_capabilities.default.jsonare removed. Setting any of those variables causes startup to fail with a structured error. There is no in-place compatibility shim — operators MUST runneotoma agents grants import --owner-user-id <usr_…>before upgrading.
What changed for npm package users
Attribution tiers and the four-tier cascade
src/crypto/agent_identity.tsadds"operator_attested"toAttributionTier;algorithmLooksHardwareBackedis deprecated and no longer participates in tier derivation. NewAttestationRevocationDiagnosticsFieldcarries the revocation sub-object inside the decision diagnostics shape.src/services/attribution_policy.tsaddsoperator_attestedtoparseMinTierandTIER_RANK(rank 3, betweensoftwareandhardware).src/services/agent_capabilities.tsextendsdefault_denytooperator_attestedfor parity withsoftware. The legacy env-driven registry loader is removed; the file now exposes the runtime contract used by the new admission path (see below).src/services/agents_directory.tsandsrc/services/recent_record_activity.tsrecognizeoperator_attestedin theirKNOWN_TIERSlists.src/services/session_info.tsranksoperator_attestedas 3 andhardwareas 4 and threads the revocation field through the/sessionresponse.src/services/feedback/admin_proxy.tsrecognizesoperator_attestedin its tier checks.src/middleware/aauth_verify.tswalks the new resolution cascade (attestation → operator allowlist → signature → clientInfo → anonymous) and populates the extendedattribution.decisiondiagnostics.attestationOutcomeForDiagnosticsmaps verifier output (including the newrevocationfield) into the request-scopedAttributionDecisionDiagnostics.
Attestation services
- New:
src/services/aauth_attestation_verifier.ts— format-dispatching entry point. DefinesAttestationFormat,AttestationFailureReason(including"revoked"),AttestationOutcome(including the optionalrevocationfield),AttestationEnvelope, andAttestationContext. NewapplyRevocationPolicy()helper centralises how revocation results affect tier resolution perRevocationModeandfailOpensetting. - New:
src/services/aauth_attestation_apple_se.ts— verifies Apple App Attestation chains against the bundled Apple App Attestation Root CA, derives the challenge fromiat+cnf.jwkthumbprint, and binds the leaf's authenticated public key to the JWT'scnf.jwkthumbprint. - New:
src/services/aauth_attestation_webauthn_packed.ts— verifies the W3C WebAuthn §8.2 packed-format statement. Parsesalg/sig/x5c/ optional AAGUID-from-cert-extension (OID1.3.6.1.4.1.45724.1.1.4), walks the chain to a trusted root, verifies the signature over the canonical attestation data, and binds the leaf credential public key tocnf.jwkvia RFC 7638 thumbprint. AAGUID admission honoursNEOTOMA_AAUTH_AAGUID_TRUST_LIST_PATH. - New:
src/services/aauth_attestation_tpm2.ts— parses the WebAuthntpmstatement (ver,alg,x5c,sig,certInfo,pubArea), walks the AIK chain to a trusted TPM CA root, verifies the signature overcertInfo, and bindspubArea's public key tocnf.jwkvia RFC 7638 thumbprint. - New:
src/services/aauth_tpm_structures.ts— internalparseTpmsAttest()andparseTpmtPublic()helpers written by hand against the TCG spec; no external TPM library dependency. - New:
src/services/aauth_attestation_trust_config.ts— loads and caches the Apple root, the bundled TPM CA roots, and any operator-supplied PEM bundle fromNEOTOMA_AAUTH_ATTESTATION_CA_PATH; loads the optional AAGUID trust list fromNEOTOMA_AAUTH_AAGUID_TRUST_LIST_PATH. - New:
src/services/aauth_operator_allowlist.ts— implements theoperator_attestedlookup againstNEOTOMA_OPERATOR_ATTESTED_ISSUERSandNEOTOMA_OPERATOR_ATTESTED_SUBS. - New:
src/services/aauth_attestation_revocation.ts— definesRevocationMode,RevocationStatus,RevocationSource,RevocationOutcome,RevocationCheckContext, andRevocationFetcher. ImplementscheckRevocation()(entry point),checkAppleRevocation()(Apple endpoint), andcheckOcspWithCrlFallback()with hand-written DER builders / parsers (no external OCSP library dependency). 24-hour LRU cache keyed by certificate fingerprint; per-lookup network timeout; fail-open by default.readRevocationMode()defaults to"enforce"when the env var is unset. - New:
config/aauth/apple_attestation_root.pem— bundled Apple App Attestation Root CA. - New:
config/aauth/tpm_attestation_roots/— bundled TPM CA roots (Infineon, STMicro, Intel, AMD), each with sourcing notes and SHA-256 fingerprint.
Agent grants and AAuth admission
- New:
src/services/agent_grants.ts— domain layer over theagent_grantentity type. CRUD helpers, validation, and an in-memory cache for identity → grant lookups. Status transitions (active→suspended↔active→revoked) are written as ordinary observations so the observation history doubles as an audit log. Identity rules: thumbprint pin wins (a rotated JWT issuer cannot quietly replace the grant); otherwise a(sub, iss)composite; otherwisesubalone. - New:
src/services/aauth_admission.ts— maps a verified AAuth identity to a Neotomaagent_grantand returns an admission decision for downstream middleware. Recordslast_used_atobservations for grants. Surfaces anAAuthAdmissionContextthat the request context propagates to write-side guards. - New:
src/services/protected_entity_types.ts— write-side guard for governance-state entity types (today:agent_grant). Enforces rules based on AAuth admission context and agent capabilities so an admitted agent cannot mutate the very grants that admit it without explicit grant scope. ExposesassertCanWriteProtected()andassertCanWriteProtectedBatch(). - New:
src/middleware/aauth_admission.ts— HTTP middleware that runs afteraauth_verify, resolves the verified identity to a grant viaaauth_admission, and writes the result onto the request context. - New:
src/cli/agents_grants_import.ts— implementation of theneotoma agents grants importcommand. ReadsNEOTOMA_AGENT_CAPABILITIES_JSON,NEOTOMA_AGENT_CAPABILITIES_FILE, orconfig/agent_capabilities.default.jsonand writes the equivalentagent_grantentities. Idempotent on(match_sub, match_iss, match_thumbprint). - New: registered
agent_grantentity insrc/services/schema_definitions.tswithcanonical_name_fieldsordered thumbprint >(sub, iss)>sub, last-write-wins reducer policies for all mutable fields, andname_collision_policy: "merge"so re-imports upsert. src/services/observation_storage.tsandsrc/services/correction.tsnow route everycreateObservationandcreateCorrectioncall throughassertCanWriteProtected({ entity_type, op, identity, admission }). Out-of-scope writes return a structured 403 withcode: "protected_entity_write_denied".src/services/request_context.tsextendsRequestContextwithaauthAdmission?: AAuthAdmissionContext | nulland exportsgetCurrentAAuthAdmission(). Absent on requests that did not pass through admission (unsigned local stdio, public discovery routes).src/actions.tsregisters admission middleware on every authenticated write route and adds the/agents/grants*REST surface (see API section).src/server.tsis wired to the admission middleware and the new admission failure mappers.
CLI signer and four hardware backends
src/cli/aauth_signer.ts:SignerBackendextended from"software"to"software" | "apple-secure-enclave" | "tpm2" | "windows-tbs" | "yubikey".generateAndStoreKeypair({ hardware: true })dispatches to the platform-appropriate backend (darwin→aauth-mac-se, Linux →aauth-tpm2, Windows →aauth-win-tbs;--backend yubikeyoverrides on any platform that has libykcs11). Falls back to the software signer with a clear "no hardware backend available" message when no backend is reachable.mintCliAgentTokenJwtmanually constructs and signs JWTs for hardware backends (DER ECDSA → JOSE r||s); software backend continues viajose.SignJWT.buildAttestationEnvelopereturns the platform-appropriate envelope:apple-secure-enclaveon macOS,tpm(WebAuthn) on Linux and Windows,webauthn-packedon YubiKey. Challenge derivation (iat+cnf.jwkthumbprint) is identical across backends.cliSignedFetch/seSignedFetchperform RFC 9421 HTTP message signatures for hardware-backed keys, inlining the necessary signature-base / header construction logic from@hellocoop/httpsig(and dispatching the DER → JOSE step through the active backend).describeConfiguredSignerreturnsbackend,se_key_tag/tpm2_handle_persistent_path/cng_key_name/yubikey_serial(whichever applies),hardware_supported, andhardware_supported_reason.neotoma auth sessionsurfaces this in both JSON and text output.hardware_supported_reasonno longer hard-codes "darwin only" on Linux and Windows.
- New optional dependencies (each lives under
packages/<name>/):@neotoma/aauth-mac-se— darwin-only; N-API binding overSecurity.framework. ExposesisSupported,generateKey,sign,attest.@neotoma/aauth-tpm2— Linux-only; N-API binding to libtss2. Same surface. Build inputs: libtss2-dev, node-gyp, C++17.@neotoma/aauth-win-tbs— Windows-only; N-API binding to TBS + CNG. Same surface. Build inputs: Windows SDK, node-gyp, MSVC.@neotoma/aauth-yubikey— cross-platform; N-API binding to libykcs11 plus the YubiKey PIVYKPIV_INS_ATTESTinstruction. Same surface. Build inputs: libykcs11 (Yubico), node-gyp, C++17. Picks the YubiKey via PKCS#11 slot enumeration; tracks the active key byyubikey_serialso a host can ship multiple YubiKey-backed signers.
- New ambient module declarations:
src/types/aauth-mac-se.d.ts,src/types/aauth-tpm2.d.ts,src/types/aauth-win-tbs.d.ts,src/types/aauth-yubikey.d.ts. The CLI dynamically imports each optional dep without a hard build-time dependency.
CLI surface
- New:
neotoma agents grants import --owner-user-id <usr_…> [--file path/to/agent_capabilities.json]. Migrates legacyNEOTOMA_AGENT_CAPABILITIES_JSON/NEOTOMA_AGENT_CAPABILITIES_FILE/config/agent_capabilities.default.jsonregistries intoagent_grantentities owned by the supplied user. Idempotent on(match_sub, match_iss, match_thumbprint). JSON-mode and human-readable summaries supported. neotoma auth keygen --hardwareworks on macOS, Linux (with libtss2 + a TPM 2.0 device), and Windows (with TBS service running and a TPM).--backend yubikeyis supported on any platform with libykcs11 and an inserted YubiKey.neotoma auth sessionreports honesthardware_supported/hardware_supported_reasonper platform and surfacesyubikey_serialwhen the active signer is YubiKey-backed.- New CLI subcommands
neotoma aauth tbs-attestation,neotoma aauth tpm2-attestation,neotoma aauth yubikey-attestation(undersrc/cli/aauth_*_attestation.ts) print the envelope each backend would mint for a given challenge — useful for diagnosing trust-config rejections without re-running the full auth flow.
Inspector and root site
frontend/src/components/MainApp.tsx,Layout.tsx, andDetailPage.tsxare updated to mount the new route sets.- New
/aauth/*pages:AauthReferencePage,AauthSpecPage,AauthAttestationPage,AauthCliKeysPage,AauthIntegrationPage,AauthCapabilitiesPage. Together they document the four-tier cascade, the attestation envelope shape, the keygen / attest CLI flows, the integration contract for downstream agents, and the per-agent capability scoping model. - New
/inspector/*pages:InspectorReferencePage,InspectorDashboardPage,InspectorEntitiesPage,InspectorObservationsAndSourcesPage,InspectorRelationshipsAndGraphPage,InspectorSchemasPage,InspectorTimelinePage,InspectorConversationsPage,InspectorAgentsPage,InspectorSearchPage,InspectorSettingsPage,InspectorSettingsConnectionPage,InspectorSettingsAttributionPolicyPage,InspectorSettingsRetentionPage,InspectorSettingsFeedbackPage. NewInspectorPreviewcomponent replaces the prior single-page Inspector demo. - New
PrimitiveRecordTypePageexposes the canonical record-type primitives (entity, entity snapshot, observation, interpretation, relationship, source, timeline event) at/primitiveswith cross-links to their subsystem docs. - The agent-detail badge tooltip and a new
AttestationEnvelopePanelrender envelope-aware fields (format, AAGUID truncated,key_binding_matches_cnf_jwk, chain summary by CN + issuer,revocationstatus with source).tierIcon()covers all four tiers;operator_attestedno longer falls through to the default glyph. frontend/src/site/site_data.ts,seo_metadata.ts,repo_info.json, anddoc_icons.tsxare updated for the new navigation, SEO entries, and icon set.frontend/src/index.cssandtsconfig.jsonare touched for the new route layouts.
API surface & contracts
Agent grants (new)
openapi.yaml adds the following routes under /agents/grants:
GET /agents/grants—listAgentGrants. List grants for the authenticated user.POST /agents/grants—createAgentGrant. Create a grant.GET /agents/grants/{id}—getAgentGrant. Read a single grant.PATCH /agents/grants/{id}—updateAgentGrant. Update editable fields (label, capabilities, notes, match fields).POST /agents/grants/{id}/suspend—suspendAgentGrant. Moveactive→suspended.POST /agents/grants/{id}/revoke—revokeAgentGrant. Moveactiveorsuspended→revoked. Terminal.POST /agents/grants/{id}/restore—restoreAgentGrant. Movesuspended→active. Cannot restore a revoked grant.
Status transitions are written as observations on the underlying agent_grant entity; the observation history is the audit log.
Attribution decision shape
attribution.decision (returned on /session and present in the attribution_decision log line) gains:
attestation:{ envelope_present, format, outcome, failure_reason, key_binding_matches_cnf_jwk, revocation? }. Therevocationsub-object is omitted (notnull) whenNEOTOMA_AAUTH_REVOCATION_MODE=disabled, so operators can distinguish "we never checked" from "we checked and gotgood". When present, its shape is{ checked: boolean, status: "good" | "revoked" | "unknown", source: "apple" | "ocsp" | "crl" | null, mode: "disabled" | "log_only" | "enforce", demoted: boolean }.operator_allowlist_source:null|"issuer_match"|"sub_match"|"issuer_and_sub_match".
AttestationFailureReason enum gains "revoked", "chain_invalid", "signature_invalid", "aaguid_not_trusted", "pubarea_mismatch", and "key_binding_mismatch" as additive members alongside the v0.7.x set. Consumers that switch on failure_reason should expect new strings; the field type remains string | null.
openapi.yaml AttributionDecision.attestation.revocation is registered as an optional sub-schema. npm run -s openapi:bc-diff -- --base v0.7.1 reports an additive change on AttributionDecision, additive routes under /agents/grants*, and no breaking changes to existing routes.
Resource metadata
-
GET /.well-known/aauth-resource-metadata.jsonreturns a dereferenceablejwks_uri:{ "issuer": "https://<authority>", "client_name": "Neotoma", "signature_window": 60, "supported_algs": ["ES256", "EdDSA"], "supported_typ": ["aa-agent+jwt"], "jwks_uri": "https://<authority>/.well-known/jwks.json" } -
New global route:
GET /.well-known/jwks.json→{ "keys": [] }. Neotoma remains verifier-only.
Sandbox AAuth
- Sandbox AAuth identity partitions by stable agent token identity (
agent_iss + agent_sub) instead of the ephemeral signing-key thumbprint. Two signed requests with the sameagent_iss + agent_subresolve to the same sandboxuser_ideven when their ephemeral key thumbprints differ. Existing thumbprint-derived rows from v0.7.1 are inert and not migrated.
Behavior changes
- Pre-v0.8.0 ES256 / EdDSA-signed agents that previously rendered as
hardwarenow render assoftwareunless they ship a verifiedcnf.attestationenvelope OR are placed on the operator allowlist (in which case they render asoperator_attested). NEOTOMA_MIN_ATTRIBUTION_TIER=hardwareis now strictly stricter than in v0.7.x — pre-attestation agents that previously satisfied this gate will be rejected withATTRIBUTION_REQUIREDuntil they upgrade. Operators rolling forward should considermin_tier=operator_attested(admits the operator allowlist + hardware) ormin_tier=softwareduring the migration window.- Revoked attestation keys demote from
hardware(oroperator_attested) tosoftwarewithfailure_reason: "revoked"by default.attribution.decision.attestation.revocation.demotedistruefor the affected requests. Operators that need a soak window can setNEOTOMA_AAUTH_REVOCATION_MODE=log_onlyahead of upgrading. NEOTOMA_AGENT_CAPABILITIES_*env vars (or the legacyconfig/agent_capabilities.default.jsonregistry) on a v0.8.0 process cause startup to fail with a structured error message pointing atneotoma agents grants import. Re-runs of the import are idempotent on(match_sub, match_iss, match_thumbprint).- Verification latency on
log_onlyandenforcemodes increases by one network round-trip on cache miss for the first request against a given attestation leaf; cache hits add ~microseconds. The 5-second timeout caps the worst case. attribution_decisionlog lines and a newattestation_revocation_check status=<…> source=<…> source_url=<…> elapsed_ms=<n>log line appear for every revocation lookup that hits the network. Cache hits are not logged. A rate-limitedattestation_demoted reason=revoked source=<…> agent_iss=<…> agent_sub=<…>line is emitted per-fingerprint when revocation actually demotes a request underenforce.- Sandbox AAuth callers now resolve to a stable
user_idacross ephemeral signing-key rotation; existing thumbprint-derived sandbox rows from v0.7.1 are inert. - Inspector users see attestation diagnostics, AAGUID admission, and revocation status inline on every signed agent. The prior tier-badge-only presentation is gone.
- AAuth admission is a valid auth path on non-Sandbox deployments. The auth chain in
src/actions.tsnow accepts a verified AAuth signature whose identity matches an activeagent_grantand resolves the request to that grant's owneruser_ideven when no Bearer header is present; missing-Bearer responses include a hint pointing at Inspector → Agents → Grants. In v0.7.x, the same request would have been rejected withAUTH_REQUIREDoutside Sandbox.
Agent-facing instruction changes (ship to every client)
docs/developer/mcp/instructions.mdanddocs/developer/cli_agent_instructions.mdare rewritten under the four-tier cascade. ThePreferred — AAuthclauses describe four tiers andcnf.attestation. The MCPPreflight your sessionrule documents the extendedattribution.decisionshape includingattestation(withrevocation) andoperator_allowlist_source. Setup docs flag that adding a new MCP server entry to.cursor/mcp.jsonrequires reloading Cursor before its in-app MCP tools (includingCallMcpTool) pick up the new server.AGENTS.mdcross-references the Cursor MCP-reload note and the new attribution / admission contract so every Codex-style consumer picks up the same instructions.
Docs site & CI / tooling
- New canonical primitive-record-type docs:
docs/subsystems/entities.mddocs/subsystems/entity_snapshots.mddocs/subsystems/interpretations.mddocs/subsystems/timeline_events.md
docs/foundation/timeline_events.mdis annotated as the doctrinal counterpart to the new architectural reference and gains a "Related Documents" section pointing at the subsystem docs and the determinism doctrine.- New AAuth subsystem docs:
docs/subsystems/aauth.md,docs/subsystems/aauth_attestation.md(envelope + verifier dispatch + revocation policy semantics + caching +enforcemigration plan),docs/subsystems/aauth_cli_attestation.md(Apple SE, Linux TPM 2.0, Windows TBS, YubiKey keygen flows;signer.jsonschema; per-platform troubleshooting; YubiKey PIV slot / PIN-cached vs PIN-always interactions). - New integration guides:
docs/integrations/aauth_tbs_windows.md,docs/integrations/aauth_tpm2_linux.md,docs/integrations/aauth_yubikey.md. - Rewritten:
docs/subsystems/agent_attribution_integration.md— four-tier cascade, extended/sessionshape, new env vars, expanded diagnostics checklist, updated CLI signer section. Now also documents the per-agent capability scoping lifecycle throughagent_grantentities and the admission contract. - Updated for the new primitives:
docs/subsystems/agent_capabilities.md,docs/subsystems/observation_architecture.md,docs/subsystems/relationships.md,docs/subsystems/sources.md,docs/subsystems/events.md,docs/subsystems/record_types.md, anddocs/doc_dependencies.yaml. - New FU scaffolds for the work consolidated into v0.8.0:
docs/feature_units/in_progress/FU-2026-04-aauth-hardware-attestation/,FU-2026-Q3-aauth-inspector-attestation-viz/,FU-2026-Q3-aauth-tpm2-verifier/,FU-2026-Q3-aauth-webauthn-packed-verifier/,FU-2026-Q4-aauth-attestation-revocation/,FU-2026-Q4-aauth-linux-tpm2-cli/,FU-2026-Q4-aauth-windows-tbs-cli/,FU-2026-Q4-aauth-yubikey-cli/.
Internal changes
- Workspace gains four new
packages/aauth-*entries (aauth-mac-se,aauth-tpm2,aauth-win-tbs,aauth-yubikey) with consistent N-API binding shape,binding.gyp, generated build artefacts, TypeScript outputs, and per-package smoke tests undertests/. src/services/aauth_attestation_verifier.tsis the single module other verifiers route through; format-specific verifiers do not duplicate trust-config orapplyRevocationPolicy()logic.- The
aauth_admissionmiddleware composes with the existingaauth_verifymiddleware; admission state propagates to the write path throughrequest_contextrather than module-level globals. frontend/tsconfig.jsonandfrontend/tsconfig.tsbuildinfoare touched for the new Inspector route set.
Fixes
- AAuth tier attribution no longer overstates trust by promoting algorithm choice to
hardware. tierIcon()no longer falls through to the default○glyph foroperator_attested; the four-tier visual cascade now matches the four-tier semantic cascade.attribution.decisionsurfaces enough information to debug attestation failures and revocation outcomes without enabling debug logging.eligible_for_trusted_writesreflects the resolved tier honestly under the new cascade and the new revocation default.neotoma auth session'shardware_supported_reasonis honest about why hardware is or is not available on Linux and Windows; the prior "darwin only" hard-code is gone.- WebAuthn-packed and TPM 2.0 envelopes that would have been silently rejected by an earlier framework version now produce real verifications (and real, format-specific failure reasons when they fail).
- A revoked attestation key that previously continued to authorise the agent at its prior tier indefinitely now demotes to
softwareunder the defaultenforcemode (and produces audit-trail evidence underlog_only). - Hardware AAuth is no longer reachable only on hosts with built-in TPM / Secure Enclave; YubiKey gives operators a portable hardware root they can carry between hosts.
- Sandbox follow-ups: real AAuth CLI flows that rotate ephemeral signing keys now perform write-read round trips against
sandbox.neotoma.io; AAuth resource discovery no longer returnsjwks_uri: null.
Tests and validation
- New unit tests:
tests/unit/aauth_attestation_apple_se.test.ts,tests/unit/aauth_attestation_webauthn_packed.test.ts,tests/unit/aauth_attestation_tpm2.test.ts,tests/unit/aauth_attestation_verifier.test.ts,tests/unit/aauth_attestation_revocation.test.ts,tests/unit/aauth_attestation_trust_config.test.ts,tests/unit/aauth_operator_allowlist.test.ts,tests/unit/aauth_tpm_structures.test.ts,tests/unit/aauth_admission.test.ts,tests/unit/aauth_authority_normalization.test.ts.tests/unit/agent_grants_service.test.ts,tests/unit/agents_grants_import.test.ts,tests/unit/agent_capabilities.test.ts(updated),tests/unit/agent_identity.test.ts(updated),tests/unit/protected_entity_types.test.ts.tests/unit/cli_aauth_tbs_attestation.test.ts,tests/unit/cli_aauth_tpm2_attestation.test.ts,tests/unit/cli_aauth_yubikey_attestation.test.ts.tests/unit/features/FU-2026-Q3-aauth-inspector-attestation-viz/agent_badge_tier_icon.test.ts.tests/unit/request_context.test.ts(updated),tests/unit/session_info.test.ts(updated).
- New integration tests:
tests/integration/aauth_tier_resolution.test.ts— locks in the four-tier resolution cascade end-to-end.tests/integration/aauth_webauthn_packed_e2e.test.ts— runtime-generated CA + leaf chain through the AAuth middleware end-to-end.tests/integration/aauth_tpm2_e2e.test.ts— runtime-generated TPM CA + AIK chain through the AAuth middleware end-to-end.tests/integration/aauth_revocation_e2e.test.ts— local HTTP impersonation of Apple's revocation endpoint; explicitly exercisesenforce,log_only, anddisabledmodes against the middleware → Apple SE verifier → revocation service path.tests/integration/agent_capabilities_store.test.ts(updated) — exercises grant-driven scoping through the new admission middleware.
- Per-package native binding tests under
packages/aauth-*/tests/cover argument validation, error mapping, and the graceful "device not present" path. Real-hardware smoke tests are skipped unlessNEOTOMA_AAUTH_TPM2_TEST_ENABLED=1,NEOTOMA_AAUTH_WIN_TBS_TEST_ENABLED=1,NEOTOMA_AAUTH_YUBIKEY_TEST_ENABLED=1, or the existing macOS Secure Enclave smoke condition holds. - Existing tier-assertion sites across
src/andtests/are updated for the new tier values, the newattribution.decisionshape, and the newfailure_reasoncodes. tests/integration/aauth_resource_metadata.test.tscontinues to lock in the dereferenceablejwks_uriand empty JWKS response.tests/integration/aauth_sandbox_attribution_partition.test.tsandtests/integration/aauth_sandbox_write_admission.test.tscontinue to validate stable agent-identity partitioning and AAuth-only write attribution to the stable agent-derived sandbox user.npm run -s openapi:bc-diff -- --base v0.7.1reports the additiveattestation.revocationfield onAttributionDecision, additive/agents/grants*routes, and no breaking changes to existing routes.
New environment variables
| Env var | Default | Purpose |
| ------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| NEOTOMA_AAUTH_ATTESTATION_CA_PATH | (bundled roots only) | Path to a PEM bundle that supplements (or replaces) the bundled Apple App Attestation Root CA and bundled TPM CA roots. |
| NEOTOMA_AAUTH_AAGUID_TRUST_LIST_PATH | (bundled defaults) | Path to a JSON allowlist of trusted AAGUIDs / vendor identifiers used by the WebAuthn-packed and TPM 2.0 verifiers. |
| NEOTOMA_OPERATOR_ATTESTED_ISSUERS | (empty) | Comma-separated iss values whose verified-AAuth callers are promoted to operator_attested. |
| NEOTOMA_OPERATOR_ATTESTED_SUBS | (empty) | Comma-separated sub values (or iss::sub pairs) whose verified-AAuth callers are promoted to operator_attested. |
| NEOTOMA_AAUTH_REVOCATION_MODE | enforce | One of disabled / log_only / enforce. Controls whether revoked status demotes the tier. |
| NEOTOMA_AAUTH_REVOCATION_CACHE_TTL_SECONDS | 86400 | LRU cache TTL keyed by certificate fingerprint. |
| NEOTOMA_AAUTH_REVOCATION_TIMEOUT_MS | 5000 | Per-lookup network timeout (Apple endpoint, OCSP, or CRL fetch). |
| NEOTOMA_AAUTH_REVOCATION_FAIL_OPEN | true | When the responder is unreachable, treat the result as unknown (true) or revoked (false). |
| NEOTOMA_AAUTH_APPLE_REVOCATION_URL | Apple production endpoint | Override the Apple anonymous-attestation revocation endpoint. Primarily for testing. |
| NEOTOMA_AAUTH_TPM2_HANDLE | 0x81010000 | Persistent TPM 2.0 handle the Linux backend uses for the AIK. |
| NEOTOMA_AAUTH_TPM2_HIERARCHY | owner | TPM 2.0 hierarchy under which the AIK is created. |
| NEOTOMA_AAUTH_TPM2_TEST_ENABLED | 0 | Enables real-TPM smoke tests in packages/aauth-tpm2/. |
| NEOTOMA_AAUTH_WIN_TBS_PROVIDER | Microsoft Platform Crypto Provider | CNG provider used by the Windows backend. |
| NEOTOMA_AAUTH_WIN_TBS_KEY_NAME | neotoma-aauth-aik | CNG key name reserved for the AIK. |
| NEOTOMA_AAUTH_WIN_TBS_SCOPE | user | user or machine. Selects the CNG scope. |
| NEOTOMA_AAUTH_WIN_TBS_TEST_ENABLED | 0 | Enables real-TPM smoke tests in packages/aauth-win-tbs/. |
| NEOTOMA_AAUTH_YUBIKEY_PKCS11_PATH | platform default | Path to libykcs11. Override when libykcs11 is not on the loader path. |
| NEOTOMA_AAUTH_YUBIKEY_SERIAL | (unset) | Pin the active YubiKey by serial when multiple devices are inserted. |
| NEOTOMA_AAUTH_YUBIKEY_PIN | (unset) | Optional PIN. PIN-cached vs PIN-always behaviour follows the YubiKey PIV slot policy. |
| NEOTOMA_AAUTH_YUBIKEY_TEST_ENABLED | 0 | Enables real-hardware smoke tests in packages/aauth-yubikey/. |
All of the above are documented in .env.example and docs/subsystems/aauth_attestation.md / docs/subsystems/aauth_cli_attestation.md.
The following env vars are removed in v0.8.0: NEOTOMA_AGENT_CAPABILITIES_JSON, NEOTOMA_AGENT_CAPABILITIES_FILE, NEOTOMA_AGENT_CAPABILITIES_ENFORCE, and the bundled config/agent_capabilities.default.json registry. Setting any of those variables on a v0.8.0 process causes startup to fail with a structured error pointing at neotoma agents grants import --owner-user-id <usr_…>.
Breaking changes
- Tier semantics changed. Agents that previously rendered as
hardwarepurely because of ES256 / EdDSA now render assoftwareunless they present verified attestation. Tooling, dashboards, ACLs, and CI gates that branch onattribution.tier === "hardware"MUST be reviewed before upgrading. Operators that need a smoother migration window should considermin_tier=operator_attested(admits the operator allowlist + hardware) ormin_tier=software. NEOTOMA_AGENT_CAPABILITIES_*removed. The env-driven per-agent capability registry and the committed default JSON file are removed. Operators MUST runneotoma agents grants import --owner-user-id <usr_…>before upgrading; setting the legacy vars on a v0.8.0 process causes startup to fail with a structured error. Re-runs of the import are idempotent.- Revocation enforcement on by default.
NEOTOMA_AAUTH_REVOCATION_MODE=enforceis the new default. Agents whose attestation keys appear on Apple's anonymous-attestation revocation endpoint, on the OCSP responder for theirwebauthn-packedleaf, or on the OCSP / CRL chain for theirtpm2AIK demote fromhardware(oroperator_attested) tosoftwarewithfailure_reason: "revoked". Operators that need a soak window should setNEOTOMA_AAUTH_REVOCATION_MODE=log_onlyahead of upgrading. attribution.decisionshape grew. New required fields underattestationandoperator_allowlist_source; new optionalattestation.revocationsub-object. Field additions are backwards compatible, but consumers that asserted exact-shape equality on the decision object will need to update.NEOTOMA_MIN_ATTRIBUTION_TIER=hardwareis stricter. Pre-attestation agents that previously satisfied this gate are rejected withATTRIBUTION_REQUIREDuntil they upgrade.
Rollback
- Sandbox: redeploy the previous sandbox image. No migrations are required.
- npm:
v0.7.1remains available; consumers can pin withnpm install [email protected]. Rolling back returns the env-driven capability registry, the algorithm-basedhardwarepromotion, and removesoperator_attested,agent_grant, and the entire attestation framework. Agents minted vianeotoma auth keygen --hardwarecontinue to verify after rollback (their signatures are unchanged) but appear at their pre-attestation tier. - A more conservative in-place rollback (without downgrading) is available for revocation:
NEOTOMA_AAUTH_REVOCATION_MODE=disabledsuppresses the lookup and any demotion. There is no in-place rollback for the agent grants migration; operators that downgrade also restore the legacy env-driven registry.
Commits (v0.7.1 → v0.8.0)
8a3b724chore(release): v0.8.07388a58release: v0.8.0 — hardware attestation, agent grants, AAuth as first-class auth
Full compare: v0.7.1...v0.8.0
- GET /.well-known/aauth-resource.json discovery endpoint
- Sandbox write partitioning by AAuth thumbprint
- POST /sandbox/aauth-only/store AAuth-required route
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.7.1 |
| Compare | v0.7.0 → v0.7.1 — view diff |
v0.7.1 is a surgical hotfix on top of v0.7.0 that turns Neotoma into a credible AAuth resource server in public form: it exposes the /.well-known/aauth-resource.json discovery endpoint everywhere, partitions sandbox writes by AAuth thumbprint so signed agents land under their own deterministic identity instead of the shared sandbox public user, and adds a sandbox-only AAuth-required write route so the “signature → admission → identity-bound provenance” chain is demonstrable end-to-end without changing any non-sandbox auth behavior.
Ship constraints
- This release is intentionally narrow. It assumes the working-tree changes for the AAuth metadata endpoint, the sandbox attribution branch (Option α), and the sandbox-only AAuth-required write route (γ-write) land before tagging. It excludes local-only and protected paths such as
docs/private/,.tmp_*, backup files, and generated cache output, and it does not assume any uncommitted internals inside dirty submodules ship unless those submodules are committed and the parent pointers are updated. - No schema changes, no migrations, no changes to the global auth admission gate, OAuth flows, Bearer flows,
/mcpadmission,aauthVerifymiddleware semantics, orsandboxDestructiveGuard.
Highlights
- Neotoma is now machine-discoverable as an AAuth resource server. Every Neotoma instance — hosted, sandbox, or self-hosted — serves
GET /.well-known/aauth-resource.jsonadvertising the issuer, supported algorithms (ES256,EdDSA), supported token typ (aa-agent+jwt), signature window (60), and an explicitjwks_uri: nullwith ajwks_uri_reasondocumenting that Neotoma is verifier-only and agents convey JWKs per-request via theSignature-Keyheader. - Sandbox writes are now identity-partitioned by AAuth thumbprint. When a request lands on the sandbox bypass branch and carries a verified AAuth signature, it is attributed to a deterministic per-thumbprint user id (derived via
ensureSandboxAauthUser) instead of the sharedSANDBOX_PUBLIC_USER_ID. Same key on two requests resolves to the sameuser_id; different keys resolve to differentuser_ids. Unsigned requests keep the existing public-user fallback unchanged. Read paths inherit the partition automatically because every read scopes byreq.authenticatedUserId. - Sandbox gains a public AAuth admission demo. A new sandbox-only route,
POST /sandbox/aauth-only/store, registered only whenNEOTOMA_SANDBOX_MODE=1, explicitly rejects unsigned requests with401 AAUTH_REQUIREDand otherwise delegates to the existing/storehandler. Verified writes round-trip through identity-scoped reads so the full “AAuth gate → admission → identity-bound provenance → identity-scoped retrieval” chain is visible in one terminal session.
What changed for npm package users
CLI / runtime
npm run start:api(and thedist/server.jsentry point) now servesGET /.well-known/aauth-resource.jsonwith the AAuth resource descriptor on every Neotoma instance, regardless of mode. Self-hosted and hosted operators get this for free; the descriptor is honest about what is supported and reflects the existing globally appliedaauthVerifymiddleware.- The internal
/storePOST handler is now exposed as a named function (handleStorePost) insidesrc/actions.ts. This is a pure code-organization refactor with no behavioral change forPOST /store; existing/storeintegration tests pass unchanged. src/services/local_auth.tsaddsensureSandboxAauthUser(thumbprint)and a smallhashStringToUserIdhelper (the existinghashEmailToUserIdnow delegates to it). The sandbox AAuth users useaauth-<short-thumbprint>@sandbox.neotoma.localas their stored email and an unguessable password hash so they cannot be used to log in via local auth.
Runtime / data layer
- The sandbox bypass branch in
src/actions.tsnow readsreq.aauth?.verifiedandreq.aauth?.thumbprint(populated by the existing globalaauthVerifymiddleware) and partitions attribution accordingly. This is the only change to existing auth-resolution code in this release; no other admission path is touched. - The new sandbox-only
POST /sandbox/aauth-only/storeroute is registered inside the existingif (isSandboxMode())block, so it physically does not exist in non-sandbox builds. It uses the samewriteRateLimitand request shape asPOST /store.
Shipped artifacts
- The npm package picks up the new metadata route handler, the
ensureSandboxAauthUser/hashStringToUserIdhelpers indist/services/local_auth.js, and thehandleStorePostextraction indist/actions.js. openapi.yamlis not materially tightened in this release; theopenapi:bc-diffpreflight reports no breaking changes versusv0.7.0.
API surface & contracts
-
New global route:
GET /.well-known/aauth-resource.json— public, no auth required, returns:{ "issuer": "https://<authority>", "client_name": "Neotoma", "signature_window": 60, "supported_algs": ["ES256", "EdDSA"], "supported_typ": ["aa-agent+jwt"], "jwks_uri": null, "jwks_uri_reason": "Neotoma is verifier-only; agent JWKs are conveyed per-request via the Signature-Key header (with thumbprint binding via the jkt claim)." }issueris derived fromcanonicalAauthAuthority(): it trusts an explicitNEOTOMA_AAUTH_AUTHORITYconfiguration first, then the host the process is listening on, and is normalized to a fully-qualified URL when possible. -
New sandbox-only route:
POST /sandbox/aauth-only/store— identical request/response shape toPOST /store, but admission is gated by a verified AAuth signature. Unsigned requests get401witherror_code: "AAUTH_REQUIRED". Registered only whenNEOTOMA_SANDBOX_MODE=1; returns404(route not registered) in non-sandbox deployments. -
No changes to
POST /store,POST /entities/query,GET /entities/:id,GET /stats, OAuth flows, Bearer flows,/mcpadmission, or any other existing route. Internal handler organization changes (extraction ofhandleStorePost) are not observable through any HTTP contract.
Behavior changes
- On
sandbox.neotoma.io(and any other deployment running withNEOTOMA_SANDBOX_MODE=1), AAuth-signed requests now land on a deterministic per-thumbprintuser_idinstead of the sharedSANDBOX_PUBLIC_USER_ID. As a direct consequence, two AAuth-signed agents see disjoint slices of the entity graph through/stats,POST /entities/query, andGET /entities/:id. Unsigned sandbox requests are unchanged: they continue to attribute toSANDBOX_PUBLIC_USER_ID. - A new log line,
auth_method=sandbox_aauth user_id=<...> thumbprint=<...>, appears for AAuth-attributed sandbox requests; the existingauth_method=sandbox_publiclog line continues to cover unsigned sandbox traffic. - Self-hosted and personal-mode deployments are not affected by either of the sandbox-only changes (α, γ-write); the only externally observable difference is the new
/.well-known/aauth-resource.jsonendpoint.
Tests and validation
tests/integration/aauth_resource_metadata.test.tslocks in the contract of the new metadata endpoint:200withapplication/json,client_name === "Neotoma",signature_window === 60,supported_algsincludesES256andEdDSA,supported_typincludesaa-agent+jwt,jwks_uri === null, andissueris a non-empty string (host or fully-qualified URL).tests/integration/aauth_sandbox_attribution_partition.test.tsmirrors the production sandbox bypass branch in a minimal Express app and exercises it via real HTTP with@hellocoop/httpsigmocked at the module level. It locks in: (i) unsigned →SANDBOX_PUBLIC_USER_ID, (ii) signed → a deterministic id distinct fromSANDBOX_PUBLIC_USER_ID, (iii) two requests with the same thumbprint → same id (deterministic), and (iv) two different thumbprints → two different ids (partitioned). Companion unit assertions coverensureSandboxAauthUserdirectly, including UUID shape, determinism per thumbprint, distinct ids per thumbprint, and rejection of empty / non-string inputs.tests/integration/aauth_sandbox_write_admission.test.tsvalidates the γ-write contract end-to-end: unsignedPOST /sandbox/aauth-only/store→401 AAUTH_REQUIRED, AAuth-signedPOST→200with the responseuser_idmatchingensureSandboxAauthUser(thumbprint).id, requests with a failed AAuth verification →401, and the route is absent (404) when not registered (the non-sandbox case). The existingtests/integration/store_*.test.tscoverage continues to validate the underlyinghandleStorePostbehavior unchanged.npm run -s openapi:bc-diff -- --base v0.7.0reports no breaking changes.
Internal changes
src/actions.tsextracts the/storePOST handler from an anonymous closure into a namedasync function handleStorePost(req, res)so bothPOST /storeand the sandbox-onlyPOST /sandbox/aauth-only/storeroute can bind it. This is a pure refactor.src/services/local_auth.tsfactors the existinghashEmailToUserIdinto a sharedhashStringToUserId(input)helper, used by bothhashEmailToUserIdand the newensureSandboxAauthUser. Behavior ofhashEmailToUserIdis unchanged byte-for-byte.
Fixes
- AAuth client libraries can now auto-configure against any Neotoma instance from a single
GET /.well-known/aauth-resource.jsonfetch instead of failing the discovery probe. - Sandbox AAuth-signed writes are no longer indistinguishable from anonymous sandbox writes: the entity graph, the Inspector,
/stats, andPOST /entities/querynow all show the signing agent's identity instead of collapsing it toSANDBOX_PUBLIC_USER_ID.
Breaking changes
None.
Rollback
- Sandbox:
flyctl deploy --config fly.sandbox.toml --image registry.fly.io/neotoma-sandbox:v0.7.0— no DB migrations to undo. The thumbprint-derivedlocal_auth_usersrows written by α are functionally inert (cannot be used to log in) and can be ignored, or pruned offline if desired. - npm:
v0.7.0remains intact on the registry; consumers can pin or downgrade withnpm install [email protected].
Commits (v0.7.0 → v0.7.1)
5a27254AAuth v0.7.1: metadata + sandbox attribution (α) + sandbox-only AAuth-required write (γ-write)98ad7f9Add Tier 2 real-LLM eval harness with passing OpenAI cassettes
Full compare: v0.7.0...v0.7.1
- Public sandbox at sandbox.neotoma.io with weekly resets
- Mode-aware root landing page (GET /)
- Admin feedback proxy without leaking secrets
Full changelog
v0.7.0 turns the hosted Neotoma story into a coherent product surface: a public sandbox with weekly resets and abuse reporting, a mode-aware root landing page for hosted instances, admin feedback proxying for the Inspector, new hosted/connect marketing routes, and the deployment/runtime plumbing to operate all of it.
Highlights
- Try Neotoma in public without installing anything.
sandbox.neotoma.ionow has a first-class sandbox mode with public writes, weekly resets,/sandbox/terms,/sandbox/report,/sandbox/report/status, and a bundled Inspector at/app. - Every hosted Neotoma can explain itself at
/. The new root landing surface serves HTML for browsers and JSON/Markdown for agents, advertises the live MCP/discovery endpoints, and renders harness-specific connect snippets prefilled to the current host. - Moderate the feedback and sandbox pipeline from the Inspector without leaking admin secrets.
/admin/feedback/*now proxies toagent.neotoma.ioonly for hardware/software AAuth tiers, while Netlify functions persist sandbox abuse reports durably outside the weekly reset cycle. - Hosted onboarding is now a connected site flow instead of scattered docs. New
/sandbox,/hosted,/connect, and/crypto-engineeringpages, plus route/SEO/navigation updates, turn the marketing site into a path from “kick the tires” to “self-host or deploy.” - Hosted legal and sandbox policy pages now ship as first-class site surfaces. The site now publishes
/terms,/privacy, and a human-readable sandbox-terms page backed by the same canonical content asGET /sandbox/terms, so hosted usage policy is explicit instead of buried in repo docs. - The site now shows the product instead of only describing it. The interactive homepage demo adds an Inspector mode and richer CLI/agent/API walkthroughs, while new illustration support gives hosted pages a clearer Inspector preview frame.
What changed for npm package users
CLI / runtime
- Hosted and self-hosted Neotoma instances now render a content-negotiated root page at
GET /, backed bysrc/services/root_landing/, instead of dropping browsers onto a generic 404. The same surface returns HTML, Markdown, or JSON depending onAccept. - Sandbox operators get a dedicated runtime mode via
NEOTOMA_SANDBOX_MODE=1, with response header stamping (X-Neotoma-Sandbox: 1), lower write limits, destructive-route blocking, and a shared demo user path for unauthenticated writes. scripts/reset_sandbox.ts,scripts/seed_sandbox.ts,scripts/sandbox_purge_entity.ts, andscripts/schedule_sandbox_reset.shadd an operator workflow for wiping and reseeding the public demo deterministically fromtests/fixtures/sandbox/manifest.json.tsconfig.scripts.jsonis introduced so the sandbox/reset/cron scripts compile intodist/scripts/*as part of the server build instead of staying tsx-only.
Runtime / data layer
src/actions.tsadds the sandbox routes (/sandbox/terms,/sandbox/report,/sandbox/report/status) and the root landing/robots surfaces (/,/robots.txt) while keeping them available across hosted modes.src/services/sandbox/transport.tsandsrc/services/sandbox/local_store.tsmirror the existing feedback transport design: local file-backed persistence for dev, HTTP forwarding for hosted moderation, and shared redaction/backstop behavior before any durable write.src/services/sandbox/seed_schema.tsseedssandbox_abuse_reportso moderation records can live in the same graph as the public demo data.
Shipped artifacts
- The npm package picks up the new runtime modules under
dist/services/root_landing/*,dist/services/sandbox/*,dist/services/feedback/admin_proxy.js, and the compiled sandbox scripts. openapi.yamlis not materially tightened in this release, and theopenapi:bc-diffpreflight reports no breaking changes versusv0.6.0.
API surface & contracts
GET /is now a product surface, not just an unhandled root: HTML for humans, Markdown for copy/paste docs flows, and JSON for agents/curl.GET /robots.txtis now mode-aware: sandbox/local deployments can stay out of search indices, while personal/prod hosts advertise only the safe public surfaces.- New sandbox routes:
GET /sandbox/termsPOST /sandbox/reportGET /sandbox/report/status
- New local admin proxy routes for the feedback pipeline:
GET /admin/feedback/preflightGET /admin/feedback/pendingGET /admin/feedback/by_commit/:shaPOST /admin/feedback/:id/status
- The sandbox report relay on
agent.neotoma.ioadds Netlify-backedPOST /sandbox/report/submitandGET /sandbox/report/statusso moderation history survives sandbox resets.
Behavior changes
- Hosted Neotoma roots now identify the deployment mode (
sandbox,personal,prod,local) and surface the correct MCP URL, Inspector URL, docs URL, and harness connect snippets for that host. - Public sandbox deployments no longer behave like a lightly skinned prod instance. Destructive routes such as
/entities/split,/entities/merge,/health_check_snapshots, and/update_schema_incrementalreturn403 SANDBOX_DISABLED, while soft deletes remain reversible. - Sandbox abuse reports are rate-limited separately from normal writes and go through PII redaction before local storage or remote forwarding.
- The Inspector-hosting path continues the post-
v0.6.0work already committed onmain: hosted static builds avoid implicit localhost defaults, support a public base path, and point Pages-hosted experiences at the sandbox API by default.
Plugin / hooks / SDK changes
@neotoma/cursor-hooksnow includes anafterToolUsehook that records passivetool_invocationobservations so timeline coverage does not depend on the agent voluntarily writing structured memory later in the turn.- The Cursor hooks installer now supports explicit install/uninstall flows, merges into an existing
.cursor/hooks.jsoninstead of clobbering it, and strips only Neotoma-owned hook entries when uninstalling. packages/cursor-hooks/hooks.template.jsonand the package README are updated to match the new hook set and install behavior.
Security hardening
- The feedback admin proxy intentionally refuses anonymous or merely “unverified client” browser sessions:
/admin/feedback/*requires a resolvedhardwareorsoftwareAAuth tier before it will forward anything toagent.neotoma.io. - Sandbox moderation transport never trusts raw reporter IPs in the forwarded payload. The Fly host hashes the submitter IP and the Netlify layer treats that hash as the provenance handle.
- Sandbox mode centralizes route gating in
src/services/sandbox_mode.tsso public-demo restrictions do not depend on scattered route-level conditionals.
Docs site & CI / tooling
- The static site grows dedicated hosted-product pages:
ConnectIndexPage,HostedLandingPage,SandboxLandingPage, andCryptoEngineeringLandingPage, plus route, navigation, icon, SEO, and analytics updates. - The hosted site also publishes synced legal/policy surfaces for
/terms,/privacy, and the sandbox terms page, with shared content helpers so the browser copy and/sandbox/termsJSON do not drift. frontend/src/components/CliDemoInteractive.tsxexpands the interactive product demo to cover chat, CLI, agentic, API, and Inspector views, using the newInspectorPreviewIllustrationasset and refreshed scenario copy.frontend/src/components/DetailPage.tsxadds automatic section dividers and hero-illustration support so the new hosted/sandbox pages can carry product art without page-specific layout hacks.docs/infrastructure/deployment.mdnow documents the hosted root landing page, GitHub Pages setup, and the Fly/Netlify deployment posture for hosted surfaces.docs/subsystems/sandbox_deployment.mddocuments the sandbox architecture, seed-data policy, weekly reset workflow, abuse reporting pipeline, and moderation runbook.fly.sandbox.tomland.github/workflows/sandbox-weekly-reset.ymladd a repeatable deployment/reset story for the public demo.services/agent-site/netlify.tomlwires the sandbox report relay endpoints into the existing feedback site alongside the scheduled webhook worker.
Internal changes
src/services/root_landing/introduces a dedicated rendering layer (html_template.ts,md_template.ts,site_nav.ts,harness_snippets.ts) so deployment-mode copy stays deterministic and testable.src/services/sandbox/formalizes sandbox-specific types, terms payloads, schema seeding, local persistence, and transport selection instead of keeping sandbox behavior inline in the main server.src/server.ts,src/actions.ts, andsrc/services/local_auth.tsare updated to support the hosted/sandbox/admin-proxy flow across both MCP and HTTP entrypoints.
Fixes
- Hosted Inspector and Pages flows are less confusing: the already-committed submodule bumps after
v0.6.0remove localhost assumptions from hosted builds and set a sane default API for public Pages-backed experiences. - The public demo now has an explicit abuse-reporting and early-purge path instead of relying on ad hoc manual cleanup.
- Remote-connect documentation is now organized by harness and hosting mode instead of leaving users to stitch together install docs and subpages manually.
- The marketing surfaces now preview the Inspector more faithfully instead of relying on placeholder or text-only affordances.
Tests and validation
npm run -s openapi:bc-diff -- --base v0.6.0reports no breaking changes.- New or updated coverage is present for the major new surfaces, including
tests/integration/root_landing.test.ts,tests/integration/sandbox_mode.test.ts,tests/integration/sandbox_report.test.ts,tests/integration/feedback_admin_proxy.test.ts,tests/unit/root_landing_harness_snippets.test.ts,tests/unit/root_landing_site_nav_drift.test.ts, andtests/unit/sandbox_reset.test.ts. - The release scope also includes fixture coverage for sandbox reseeding under
tests/fixtures/sandbox/.
Breaking changes
No breaking changes.
- GET /session preflight for AAuth verification
- observation_source tagging for write classification
- conversation_message with sender_kind for multi-agent chat
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.6.0 |
| Compare | v0.5.1 → v0.6.0 — view diff |
v0.6.0 is an agent-runtime hardening release: AAuth-aware attribution and a /session preflight land across every write surface; closed OpenAPI request shapes now reject unknown top-level fields with a structured ERR_UNKNOWN_FIELD; writes can be classified by observation_source; multi-agent chat becomes first-class via conversation_message + sender_kind; over-merged entities are recoverable through POST /entities/split; an agents directory and richer provenance reads land; a full submit→queue→triage→mirror→upgrade/verify feedback pipeline ships (local store, HTTP transport, and a Netlify-hosted agent-site relay at agent.neotoma.io); fleet snapshot export + drift tooling lands via neotoma snapshots; and API security defaults tighten (Helmet CSP, per-user write rate limiting, timing-safe token compare, socket-based loopback classification). The previously planned neotoma api start --env prod default-runner flip ships in the same release.
Highlights
- Know which agent wrote what. Neotoma verifies AAuth-signed requests, stamps a trust tier on every observation/relationship/source/interpretation, and exposes a preflight (
GET /session,get_session_identity,neotoma auth session) so agents can confirm they are seen as a real, signed writer before producing any data. - Your whole agent fleet upgrades with the server. The MCP instructions the server ships to every connected client now codify AAuth preflight,
observation_sourcetagging, reply-cited provenance edges (Step 5b.1), anAmbiguous (N)display group for heuristic merges, and the structured feedback-submission loop — so every connected agent picks up the new defaults on server upgrade without client-side changes. - Fleet-grade write integrity. Tag writes with
observation_source(sensor/workflow_state/llm_summary/human/import) — accepted on/store, MCP store tools, andneotoma store --observation-source— then export canonical snapshots and diff them against external state (MEMORY.md, shadow DBs, other fleets) with explicit field-level and provenance-gap reports vianeotoma snapshots export|diff|parsers|check|request. - Multi-agent conversations as first-class data.
conversation_messagewithsender_kind(user/assistant/agent/system/tool) plus stablesender_agent_id/recipient_agent_idgive real agent-to-agent routing and reporting;thread_kind(human_agent/agent_agent/multi_party) describes participant topology; stricterturn_key/conversation_idguidance keeps unrelated threads from silently merging. - A structured agent feedback loop. Agents can
submit_feedback, poll for resolution withget_feedback_status(respectingnext_check_suggested_at), receive install/upgrade guidance, and verify fixes; the newagent.neotoma.ioNetlify service relays, redacts, and optionally forwards each item into Neotoma so one-off bug reports become a machine-ingestible pipeline. - Repair over-merged entities without destructive edits.
POST /entities/splitand thesplit_entityMCP tool rebind a subset of observations to a new entity by time range, source, or field match, producing anentity_splitsaudit record instead of an irreversible delete/re-insert.
What changed for npm package users
CLI (neotoma)
neotoma auth session— callsGET /sessionand prints the resolved trust tier, identity, andeligible_for_trusted_writes, merging any localcli_signerstate.neotoma auth keygen— writes a local AAuth keypair under~/.neotoma/aauth/; flags:--alg,--sub,--iss,--force.neotoma auth sign-example— prints a signedcurlexample targeting/sessionso operators can sanity-check signing end-to-end.neotoma api start --env prodon source checkouts now defaults to the built production runner (dist/…) instead of thedev:prodwatcher. Pass--watchto restore the previous tsx-watcher behavior underNEOTOMA_ENV=production.--observation-source <kind>is threaded through store-oriented flows so operators/agents can label writes assensor,workflow_state,llm_summary,human, orimportinstead of treating every write as equivalent.neotoma feedback mode <proactive|consent|off>— controls whether agents auto-submit feedback, prompt for consent, or stay silent unless explicitly asked.neotoma triage— ingest pending feedback; flags:--watch,--list-pending,--set-status,--resolve,--health,--mirror-replay,--dry-run, plus resolution-link options.neotoma snapshots check|request|export|diff|parsers— offline-first fleet audit tooling: export canonical snapshots of local state, request snapshots from a remote Neotoma viaPOST /health_check_snapshots, diff against external sources (MEMORY.md, shadow DBs), and report on supported parsers.- New npm scripts:
openapi:bc-diff(release preflight for breaking contract changes),feedback:seed-schema(provision theproduct_feedbackentity schema),feedback:mirror-backfill(replay historical feedback through the mirror).
Runtime / data layer
- Request pipeline now stages JSON parsing with a raw-body stash (for signature verification), then Morgan, then an
unknownFieldsGuardthat rejects undeclared top-level keys on closed schemas before route handlers run. - Helmet CSP tightens by default (
connectSrc: ['self']); operators can allow additional hosts viaNEOTOMA_CSP_CONNECT_SRC(comma-separated list). - Per-user/IP write rate limit lands via
writeRateLimitwith a default cap of 120 writes/minute, tunable throughNEOTOMA_WRITE_RATE_LIMIT_PER_MIN; keyed by authenticated user when available, falling back to an IPv6-safe IP helper. Separate rate limiters apply to the OAuth initiate/callback/token/register routes. - AAuth verification runs non-blocking by default;
NEOTOMA_AAUTH_STRICT=1causes signed-but-invalid requests to fail with 401. AAuth is honored on every HTTP surface (/mcp,/store,/observations/create,/create_relationship,/correct,/session, …) and the same identity is threaded into write-path services regardless of transport (HTTP/mcp, MCP stdio, CLI-over-MCP, CLI-over-HTTP). - Operator-secret compares are timing-safe; loopback classification now inspects the actual socket address instead of trusting the
Hostheader, so tunneled requests no longer masquerade as local. - The observation reducer tie-breaks on
observation_sourceaftersource_priority, so classified writes win over unclassified legacy rows deterministically. - New service areas: entity split, attribution policy, request context, agents directory, agent capabilities registry, feedback transport/local-store/redaction/next-check/verification-request, snapshot export, drift comparison.
- SQLite adapter and schema registry are updated to carry the new agent attribution,
conversation_message/sender_kind,observation_source, and provenance fields end to end.
Shipped artifacts
openapi.yamlgrows ~900 lines for the new session, agents, entity-split, attribution, provenance, feedback, and validation surfaces;src/shared/openapi_types.tsis regenerated to match.- Updated schema snapshots land under
docs/subsystems/schema_snapshots/forconversation(v1.0–v1.2),agent_message(v1.0–v1.1, retained as alias), and newconversation_message(v1.0–v1.2). - The npm package picks up the CLI/runtime changes plus the updated docs and snapshots via the existing
fileslist (dist,openapi.yaml,openclaw.plugin.json,skills,LICENSE,README.md). Thefileslist itself is unchanged.
API surface & contracts
New HTTP routes
GET /session— resolved attribution tier, client identity, anonymous-write policy, andeligible_for_trusted_writes, plus a diagnosticattribution.decisionblock explaining why the tier resolved the way it did.GET /agents,GET /agents/{key},GET /agents/{key}/records— agents directory: list known agents, fetch per-agent detail, and audit which records a given agent authored.POST /entities/split— rebind a subset of observations from a source entity to a new entity by time range, source, or field match; writes anentity_splitsaudit row.GET /sources/{id}/relationships— enumerate relationships associated with a source without ad-hoc queries.POST /health_check_snapshots— fleet snapshot export endpoint consumed byneotoma snapshots check|request.
Expanded existing routes
GET /sources/{id}now includes aprovenanceblock describing where the source came from.POST /create_relationshipresponses andGET /relationships/{id}include anagent_attributionblock.POST /entities/queryacceptsidentity_basisfor finer-grained resolution/query semantics.POST /relationships/snapshotaccepts an optionaluser_idfor scoped snapshots.Observation,TimelineEvent,Interpretation, andSourceresponse shapes carry richer provenance fields so reads surface the same attribution metadata writes produce.StoreResolutionIssue.hintand related error payloads are expanded with migration-oriented guidance instead of opaque resolution failures.
New MCP tools
get_session_identity— MCP equivalent ofGET /session; use ininitializeor before enabling writes.split_entity— MCP equivalent ofPOST /entities/split.submit_feedback/get_feedback_status— feedback submission and polling (see the Agent feedback pipeline section).health_check_snapshots— MCP equivalent of the new fleet-snapshot endpoint.npm_check_update— checks for newerneotomanpm releases so agents can prompt users to upgrade when their client version falls behind.
Validation tightening
Unknown top-level fields are now rejected early (before route handlers) on closed request bodies with HTTP 400, error_code: ERR_UNKNOWN_FIELD, and a structured details payload containing allowed_fields, unknown_fields, and json_paths. See Breaking changes for the full list of affected routes and migration paths.
Behavior changes
neotoma api start --env prodon source checkouts runs the built artifact by default. The olddev:prodwatcher path is no longer the default production route; pass--watchwhen you explicitly want watcher behavior.- Unknown top-level request fields on closed write/auth endpoints fail fast. The
unknownFieldsGuardruns before route handlers, so extra JSON keys that previously slipped through are now rejected with a structured allow-list instead of being silently ignored or stripped downstream. - Session attribution is now inspectable. Operators and agent builders can query the active trust tier, client identity, and anonymous-write policy via
GET /session/get_session_identity/neotoma auth sessioninstead of inferring it from logs or headers. - Stricter browser-side defaults. The default Helmet CSP allows only
connect-src 'self'; deployments that relied on permissive outbound browser connections need to setNEOTOMA_CSP_CONNECT_SRC. - Write traffic is rate-limited by default. Bursty writers see HTTP
429after 120 writes/minute per user or IP; tune withNEOTOMA_WRITE_RATE_LIMIT_PER_MIN. - Loopback-only routes no longer trust the
Hostheader. Requests that route via tunnels or proxies are correctly classified as remote even when they carry a localhost host. - Store responses may include a
warnings[]block. Heuristic-merge ambiguity (R3) is surfaced as a structured warning; agents following the shipped MCP instructions render these under anAmbiguous (N)section in chat. - Chat hooks emit
conversation_messagewithsender_kind. Cursor, Claude Code, Codex, OpenCode, and Claude Agent SDK hook packages all produce the new canonical shape;agent_messagecontinues to be accepted as an alias at write time. - Reducer outputs may shift. When
observation_sourceis set on a new write, it tie-breaks against unclassified legacy observations via the reducer'ssource_priority→observation_sourceordering; snapshots of mixed-classification entities can change accordingly.
Agent-facing instruction changes (ship to every client)
The MCP server ships docs/developer/mcp/instructions.md to every connected client as its operating guidance, so these are user-facing behavior changes for every connected agent:
observation_sourceusage — agents are instructed to set it only for non-LLM-summary writers (sensor emitter, state-machine step, human confirmation, bulk import) and leave it unset for ordinary chat extraction.conversation_messagecanonicalization — new writes useconversation_message+sender_kind;agent_messageremains an accepted alias for pre-v0.6 clients.- A2A fields — agent-to-agent traffic is expected to set
sender_kind: "agent"withsender_agent_id/recipient_agent_id;conversation.thread_kindcategorizes the thread topology. - Reply-cited provenance edges (Step 5b.1) — the closing assistant store now includes
REFERS_TOedges from the assistant message to every entity the reply materially cites or produces, tightening the provenance graph without linking every retrieval result. Ambiguous (N)display group — agents surface structuredHEURISTIC_MERGEwarnings from store responses in chat alongsideCreated/Updated/Retrieved.[ATTRIBUTION & AGENT IDENTITY]block — codifies AAuth preflight viaget_session_identity/GET /session/neotoma auth session, forbiddenclientInfovalues, trust-tier badging, and impersonation policy.[FEEDBACK REPORTING]block — when to submit feedback, PII redaction expectations, persisting aproduct_feedbackrecord withaccess_token, polling viaget_feedback_status, handlingupgrade_guidance, and responding toverification_request.npm_check_updatehint — agents may call it at session start and prompt the user to upgrade when a newerneotomaclient is available.
docs/developer/cli_agent_instructions.md mirrors these rules for CLI-backed flows, and AGENTS.md adds an Agent Identity & Attribution section pointing at both.
Plugin / hooks / SDK changes
packages/cursor-hooks—before_submit_prompt.tsandstop.tsemitconversation_message+sender_kindand propagate AAuth-aware session metadata.packages/codex-hooks—session_end.pypropagates session/agent metadata on stop.packages/claude-code-plugin—stop.pyanduser_prompt_submit.pyalign with the new message shape and attribution fields.packages/opencode-plugin— updated to match the same conventions.packages/claude-agent-sdk-adapter— attribution/session metadata threaded through the adapter.packages/client(TypeScript client) —helpers.tsexposesChatTurnSenderKind, the newsender_kind, A2A id fields, and canonicalconversation_messagetyping;diagnose.tsandturn_report.tsalign with the new attribution/diagnostic surface.
Agent feedback pipeline (end-to-end)
- MCP entry points —
submit_feedbackfor agents to report friction;get_feedback_statusfor polling with backoff respectingnext_check_suggested_at. - Transport selection —
NEOTOMA_FEEDBACK_TRANSPORT=local|http,AGENT_SITE_BASE_URL,AGENT_SITE_BEARER; kill-switchNEOTOMA_FEEDBACK_AUTO_SUBMIT=0disables proactive submission. - Local store —
src/services/feedback/local_store.tspersists records to disk for dev/cron flows when HTTP transport is not configured. - Redaction — emails, phone numbers, tokens, UUIDs, and home-directory path fragments are replaced with
<LABEL:hash>placeholders before submission; the server returns aredaction_previewso agents can audit what was transformed. - Upgrade guidance — resolved items can carry
upgrade_guidance(install_commands,verification_steps) andverification_request(withverify_by);feedback_upgrade_guidance_map.jsoncatalogs the canonical responses. - Netlify
agent-site(services/agent-site/) — public/feedback/submit+/feedback/status, admin/feedback/pending,/feedback/{id}/status,/feedback/{id}/mirror_replay,/feedback/by_commit/:sha,/jwks,/healthz, and a scheduledpush_webhook_worker. Optionally forwards each item into Neotoma via tunnel + Cloudflare Access + AAuth (seedocs/subsystems/feedback_neotoma_forwarder.md). - Cron ingestion —
scripts/cron/ingest_agent_incidents.tsclassifies queued feedback, applies the upgrade-guidance map, and updates status;scripts/cron/com.neotoma.feedback-ingest.plist.templateprovides a launchd template. - Backfill + seeding —
scripts/feedback_mirror_backfill.tsreplays historical submissions;scripts/seed_product_feedback_schema.ts(vianpm run feedback:seed-schema) provisions theproduct_feedbackentity schema in a Neotoma instance. - Capability registry —
config/agent_capabilities.default.jsonpins[email protected]toneotoma_feedbackoperations only, so the forwarder cannot perform unrelated writes even if its key is used (docs/subsystems/agent_capabilities.md).
Security hardening
- Default Helmet CSP with explicit
connect-srcallow-list viaNEOTOMA_CSP_CONNECT_SRC. - Per-user write rate limit (
NEOTOMA_WRITE_RATE_LIMIT_PER_MIN, default 120/min) plus dedicated OAuth-route limiters. - Timing-safe equality on operator-secret compares.
- Raw-body capture ahead of JSON parsing so AAuth signature verification operates on the exact bytes clients signed.
- Loopback/local classification uses the socket address, not
Host. - AAuth strict mode (
NEOTOMA_AAUTH_STRICT=1) and optional subject allow-list (NEOTOMA_STRICT_AAUTH_SUBS) for deployments that want hard failures or per-tier ACLs. - Capability registry caps what registered service agents can do, independent of key validity.
- A security audit summary lands at
docs/reports/security_audit_2026_04_22.md.
Docs site & CI / tooling
Docs added or expanded
- Operator / integrator:
docs/subsystems/agent_attribution_integration.md,agent_capabilities.md,agent_feedback_pipeline.md,feedback_neotoma_forwarder.md,feedback_auto_pr_config.json,feedback_upgrade_guidance_map.json;docs/developer/fleet_onboarding.md;docs/architecture/openapi_contract_flow.md,docs/architecture/change_guardrails_rules.mdc; expandeddocs/subsystems/auth.md,errors.md,sources.md,entity_merge.md;docs/infrastructure/deployment.md;.env.examplegrows by ~125 lines documenting the new knobs. - Agent-author:
docs/developer/mcp/instructions.md,docs/developer/cli_agent_instructions.md,docs/developer/cli_reference.md,docs/developer/mcp/tool_descriptions.yaml,AGENTS.md; field validation and schema-agnostic rules adjusted where new fields required it. - Contributor / release:
docs/developer/github_release_process.md(now documents the mandatory Highlights drafting rule),docs/developer/github_release_supplement.example.md,docs/developer/agent_instructions_sync_rules.mdc,docs/developer/package_scripts.md.
CI / tooling
scripts/openapi_bc_diff.js+npm run openapi:bc-diff— release preflight that enumerates breaking OpenAPI changes vs a base ref.tests/contract/legacy_payloads/corpus plusreplay.test.ts— pre-v0.6 request shapes are exercised explicitly on every CI run so future tightenings cannot silently break older clients.scripts/migrate/rename_agent_message_to_conversation_message.ts— migration helper for stores that want to canonicalize historic chat rows.
Internal changes
- Middleware stack carries request context, unknown-field validation, AAuth verification, and attribution-aware session plumbing end to end.
- New service areas for agents directory, agent capabilities, attribution policy, entity split, request context, snapshot export, drift comparison, feedback transport (local + HTTP), redaction, next-check computation, and verification-request handling.
- Hook/plugin packages across Cursor, Claude Code, Codex, OpenCode, and the Claude Agent SDK adapter propagate agent/session metadata consistently.
- SQLite adapter and schema registry are updated to persist the new attribution and classification fields.
- Frontend (
frontend/src/components/MainApp.tsx,subpages/McpReferencePage.tsx,site/repo_info.json,site/site_data.ts) and Inspector (inspector/submodule pointer + entity-link component) receive alignment edits for the new chat/attribution contracts.
Fixes
- Store-resolution failures point callers at missing identity inputs more clearly, reducing silent coalescing and making chat-thread persistence easier to debug.
- Local-only detection uses the connection socket address instead of trusting
Host, closing a tunneled-request masquerade vector. - Operator-secret equality checks are timing-safe.
- OpenAPI + generated types + docs are re-synced so the published contract matches runtime behavior (the v0.5.x
attributes-nested resolver regression class cannot recur silently because the contract is now closed-by-default and exercised by legacy-payload replay).
Tests and validation
- New integration/unit coverage lands for AAuth attribution stamping, attribution parity across transports, session introspection, observation-source round-trips, agent-runtime schema definitions, drift comparison, request-context handling, unknown-field rejection, anonymous-write policy, agents-directory API, agent-capabilities store, feedback pipeline (happy path, tunnel-down, local vs HTTP, smoke, Simon Apr 21 replay), MCP stdio attribution, record-activity attribution, relationship-attribution API, and observation-source round-trips.
tests/contract/legacy_payloads/exercises v0.4.x, v0.5.x, and v0.6.x request shapes against the current server to guard against silent shape regressions.node scripts/openapi_bc_diff.js --base 'v0.5.1^{commit}'reports the breaking validation tightenings below; this supplement names each one explicitly with a migration path.- Existing CLI/unit tests (
cli_api_start_prod_advisory.test.ts,cli_api_start_watch_flag.test.ts,cli_store_commands.test.ts,client_helpers.test.ts,entity_resolution.test.ts,schema_definitions.test.ts,tunnel_auth.test.ts) were updated to reflect the new defaults.
Breaking changes
POST /store,components.schemas.StoreRequest, andcomponents.schemas.StoreStructuredRequestnow reject undeclared top-level fields. Before: extra root-level keys could pass through the HTTP layer and be silently stripped or ignored later. After: requests with unknown top-level fields fail with HTTP400,error_code: ERR_UNKNOWN_FIELD, and a structured details payload containingallowed_fields,unknown_fields, andjson_paths. Migration: send only declared top-level keys (entities,relationships,source_priority,observation_source,idempotency_key, file-related fields,commit,strict,user_idas applicable) and move entity-specific data inside the individualentities[]objects.POST /store/unstructuredandcomponents.schemas.StoreUnstructuredRequestnow reject undeclared top-level fields. Before: callers could include extra wrapper keys alongside the upload payload. After: HTTP400witherror_code: ERR_UNKNOWN_FIELDand a structured details payload. Migration: limit the body tofile_content,mime_type,idempotency_key,original_filename,user_id.POST /relationships/snapshotandcomponents.schemas.GetRelationshipSnapshotRequestnow reject undeclared top-level fields. Before: extra keys could slip through until the route-level validator ran. After: rejected earlier with HTTP400/ERR_UNKNOWN_FIELD. Migration: send onlyrelationship_type,source_entity_id,target_entity_id,user_id(the last is newly optional).POST /mcp/oauth/initiateandcomponents.schemas.OAuthInitiateRequestnow reject undeclared top-level fields. Before: callers could include extra auth-initiation metadata at the request root. After: HTTP400/ERR_UNKNOWN_FIELD. Migration: restrict requests toconnection_id,client_name,redirect_uri.POST /correctnow rejects undeclared top-level fields. Before: extra root-level keys were not contractually forbidden at the HTTP boundary. After: HTTP400/ERR_UNKNOWN_FIELD. Migration: limit the body toentity_id,entity_type,field,value,idempotency_key,user_id.neotoma api start --env prodon source checkouts now runs the built runner by default. Contributors or automation that relied on the olddev:prodwatcher must switch toneotoma api start --env prod --watch. Thedev:prodnpm script alias itself is unchanged.- Default Helmet CSP restricts
connect-srcto'self'. Deployments that served browser UI from the API and relied on permissive outbound connections must opt in viaNEOTOMA_CSP_CONNECT_SRC. - Default write rate limit of 120 writes/minute per user/IP. Bursty writers receive HTTP
429; tune viaNEOTOMA_WRITE_RATE_LIMIT_PER_MINor batch viastore_structured. - Loopback classification changed. Requests routed through tunnels/proxies are no longer treated as local even when they carry a localhost
Hostheader; deployments that relied on this behavior for lightweight dev-auth must switch to AAuth or an explicit allow-list.
Commits (v0.5.1 → v0.6.0)
dd5ed95Bump version to v0.6.06a58115Pre-release: include changes for v0.6.0
Full compare: v0.5.1...v0.6.0
- StoreStructuredResponse.replayed field for idempotency detection
- NEOTOMA_USER_ID env var for uniform tenant scoping
- Auto-upload file_content for non-localhost transports
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.5.1 |
| Compare | v0.5.0 → v0.5.1 — view diff |
v0.5.1 started as a verification-follow-up patch to v0.5.0 and also folds in inspector/read-model enrichments that were already in the working tree before tagging. It adds uniform tenant-scoped reads (a NEOTOMA_USER_ID env var and missing --user-id flags), surfaces store idempotency replays explicitly with a new replayed response field, adds a structured upgrade hint when the legacy attributes-nested payload shape hits ERR_STORE_RESOLUTION_FAILED, lets neotoma ingest auto-upload file bytes over remote/tunneled transports, ships a headless production deployment guide in install.md plus a one-line CLI advisory so neotoma api start --env prod on a source checkout is no longer silent about routing through the tsx watcher, and expands inspector-facing HTTP responses for recent conversations, recent activity, and entity/relationship detail views.
What changed for npm package users
CLI (neotoma, neotoma api start, neotoma ingest, …)
- New
--user-idflags onneotoma entities getandneotoma stats(the two read verbs that were missing them); existing read verbs continue to honor--user-id. - New
NEOTOMA_USER_IDenvironment variable withflag > env > defaultprecedence, joiningNEOTOMA_API_ONLYandNEOTOMA_OFFLINEin the CLI's transport/preAction layer. Read verbs (entities list/get/search/find-duplicates,observations list/get,relationships list,timeline list/get,schemas list,sources list,stats,recent,memory-export) all resolve their effective user id through the same helper so tenant scoping is uniform. Empty/whitespace env values are rejected so shell expansion mistakes surface immediately instead of silently falling through toLOCAL_DEV_USER_ID. neotoma storeandneotoma store-structurednow print a stderr warning in commit mode when the response reportsentities_created=0and the server did not flag the call as an idempotency replay (replayed: true) and no existing entities were matched/updated. This catches the v0.5.0 "silent zero-commit" verification symptom regardless of its underlying cause, and suggests the three usual culprits (flattenattributes, check user scope, check registered schema).neotoma ingestgrows two new flags:--source-uploadforces byte upload regardless of transport;--source-content <inline>skips the filesystem entirely and base64-encodes the provided string. By default,ingestnow auto-detects non-localhost base URLs (tunnel / remote production) and switches fromfile_pathtofile_contentso tunneled client/server topologies no longer fail withENOENTwhen the server can't read the client's filesystem. Localhost / offline callers keepfile_pathto avoid the base64 memory hit on large blobs. The CLI enforces a ~7.5 MB upload cap (chosen against the server's 10 MB JSON body limit, accounting for base64 overhead) and aborts with a clear error before network I/O when exceeded.neotoma api start --env prodon a source checkout now emits a one-line stderr advisory before spawning the tsx watcher (dev:prod) to make the routing visible and point operators at the supervised systemd recipe. Suppressed under--output jsonto preserve machine-readable output. Does not fire on--env dev, on installed-package checkouts without source watch scripts, or on the tunnel path.
Runtime / data layer
POST /store(StoreStructuredResponse) now carries an explicitreplayed: booleanfield.trueon the existing-source idempotency-replay branch (same(user_id, idempotency_key)as a prior commit);falseon the fresh-write branch. Every response path sets the field explicitly so clients can rely on it rather than inferring replay state from other shape signals. Entity hash, idempotency keying, and observation/source determinism are unchanged.ERR_STORE_RESOLUTION_FAILEDissue objects gain an optionalhint: stringfield. The server populates it with structured upgrade guidance whenCanonicalNameUnresolvedError.seen_fieldsis exactly{"attributes"}or{"entity_type", "attributes"}— i.e. a caller is still sending the pre-0.5.0attributes: { … }wrapper. The hint text is schema-guidance only (no caller payload values are echoed back) and is absent for unrelated unresolved-name scenarios.
Shipped artifacts
openapi.yamldeclares:user_idas an optional query parameter onGET /entities/{id}andGET /stats;replayed: booleanonStoreStructuredResponse; newStoreResolutionIssue(withhint) andStoreResolutionErrorEnvelopeschemas;StoreResolutionErrorEnvelopewired to the400response forPOST /store. The same contract pass also carries inspector-facing response enrichments already in the tree: extra entity detail metadata (entity_type_label,primary_fields,created_at), richer relationship expansion fields, and theGET /recent_conversationsoperation.src/shared/openapi_types.tsregenerated to match.
API surface & contracts
- New response field:
StoreStructuredResponse.replayed: boolean(set on every response path — replay and fresh-write). - New query params (additive, existing server handlers already honor them):
GET /entities/{id}?user_id=…,GET /stats?user_id=…. Theuser_idparam is optional and is still validated through the existinggetAuthenticatedUserIdgate; it does not widen the existing dev-override surface (onlyLOCAL_DEV_USER_IDauth contexts may pass a differentuser_id; real Bearer-authenticated callers still get 403 on mismatched ids). - New error field:
StoreResolutionIssue.hint?: string(optional). Emitted today for theattributes-nested payload case; the schema allows the same structured hint surface to carry future targeted guidance without another breaking change. - Inspector/read-model additions already in the branch:
GET /recent_conversations, richerGET /entities/{id}response metadata (entity_type_label,primary_fields,created_at), and expandedGET /entities/{id}/relationships?expand_entities=trueresponse fields for caller-friendly source/target labels.contract_mappings.tsnow mapsgetRecentConversationsas an HTTP-only infra surface.
Behavior changes
/storeidempotency replay is now explicit. Clients that inspectedentities_created_count: 0as a proxy for replay-vs-failure should switch to the newreplayedfield. The CLI's new commit-mode stderr guard does exactly this: it fires only whenentities_created=0ANDreplayed !== trueAND no entities were matched/updated.attributes-nested payloads surface upgrade guidance. Callers still sending{"entity_type": "…", "attributes": { … }}receive a structuredhintin everyERR_STORE_RESOLUTION_FAILEDissue pointing them at the flat post-0.5.0 shape and the v0.5.0 release notes. Behavior is still a 400 error; no compat shim (aligns with v0.5.0 R1/R2 strictness).neotoma ingestover remote transports changes its request shape automatically. Non-localhost / non-offline base URLs sendfile_content(base64) +mime_type+original_filenameinstead offile_path. Localhost and offline callers are unchanged. Force with--source-upload; opt out by passing explicit inline content with--source-content.neotoma api start --env prodis no longer silent on source checkouts. It still routes throughdev:prod(tsx watcher) for contributors who rely on hot-reload inNEOTOMA_ENV=production, but now prints a single stderr line directing headless-deployment operators at the supervised systemd recipe ininstall.md. The default routing fix itself is deferred to a separate phased plan (v0.5.2 → v0.6.0); v0.5.1 only ships the advisory.- Inspector views get richer server-computed payloads.
record_activityitems now carry typed enrichment fields (entity_name,source_filename, relationship/entity ids,group_key, etc.) so the UI can group or decorate entries without re-querying.recent_conversationsreturns nested conversation → message → linked-entity structures ordered by latest activity. Entity detail responses expose schema-derived labels and primary fields so overview cards can render without duplicating schema-order logic client-side.
Breaking change notice (retroactive to v0.5.0)
v0.5.0's schema-agnostic strictness (R1/R2) dropped the undocumented attributes: { … } wrapper convention that some pre-0.5.0 clients used when building /store payloads. Callers wrapping entity fields in attributes now receive ERR_CANONICAL_NAME_UNRESOLVED instead of silently writing. This was the intended behavior under R1/R2 (the attributes wrapper was never a schema-registry concept — just a client convention), but it was not flagged in the v0.5.0 release notes. v0.5.1 retroactively documents the break and adds the structured hint above to make the fix obvious.
Before (pre-0.5.0):
{
"entity_type": "person",
"attributes": { "email": "[email protected]", "full_name": "Ada Example" }
}
After (v0.5.0+):
{
"entity_type": "person",
"email": "[email protected]",
"full_name": "Ada Example"
}
Docs site & CI / tooling
docs/developer/cli_reference.mdadds:NEOTOMA_USER_IDrow in the Runtime overrides table with precedence and empty-value rejection.- Store section entries for the new
replayedflag and the commit-mode stderr guard. - New Ingest section documenting
--source-upload,--source-content, the localhost/remote auto-detection heuristic, and the upload size cap.
docs/developer/cli_agent_instructions.mdgains matching bullets under[CONVENTIONS](User scope, Ingest source transport, Silent-failure guard), propagated through the anchor-table rule in.cursor/rules/developer_agent_instructions_sync_rules.mdc(anchor rows 72b / 72c / 72d; CLI-only).neotoma cli-instructions checkcontinues to pass.docs/developer/mcp/instructions.mdkeeps the v0.5.1 CLI/MCP parity bullets and also adds human-readable naming guidance for chat artifacts (agent_message.canonical_nameandconversation.title) so stored chat rows present better labels downstream.install.mdadds a new Production deployment (headless / systemd) subsection with a testedneotoma.serviceunit file, env var list, theProtectSystem=no/PrivateTmp=nocaveat for/usr/lib/node_modules/neotomaresolution, and a forward reference todocs/operations/runbook.md.docs/operations/runbook.mdcross-links back to the new install-md section from its production deployment block.docs/subsystems/auth.mddocuments the tenant-scoped-read pathway end-to-end (flag > env > default >LOCAL_DEV_USER_ID) and makes explicit that the dev-override surface is not widened.docs/subsystems/errors.mddocuments the newhintfield onERR_STORE_RESOLUTION_FAILEDissues.
Internal changes
src/actions.ts:storeStructuredForApisetsreplayed: trueon the idempotency-replay branch andreplayed: falseon every fresh-commit return path; theCanonicalNameUnresolvedError→ HTTP mapping computes anattributes-specific hint via a newbuildAttributesHinthelper and preserves the optionalhintfield through the error envelope.src/cli/index.ts: newresolveEffectiveUserId()helper threads--user-id/NEOTOMA_USER_IDthrough every read verb; newisLocalhostBaseUrl()helper handles IPv4, IPv6, and hostname-equivalence cases; new--source-upload/--source-contentflags and auto-upload branch oningest; commit-mode stderr guard onstore/store-structured; stderr advisory onapi start --env prod(background branch is guarded onoutputMode !== "json").- Inspector/read-model services:
src/services/recent_conversations.tsadds a SQLite-backed recent-conversations aggregator with nested message/entity expansion;src/services/recent_record_activity.tsexposes richer typed fields and a server-computedgroup_key;src/services/entity_queries.tsadds schema-derivedentity_type_labelandprimary_fields;src/shared/contract_mappings.tsmaps the HTTP-onlygetRecentConversationsoperation.
Fixes
store --filevsstore --entitiesparity. WithNEOTOMA_USER_IDfixed on both calls, both paths create equivalent entities with the sameentities_created_count, identical entity ids, and the samereplayedflag on repeat calls with the same--idempotency-key. This closes the v0.5.0 "silent zero-commit" report; the root cause was tenant-scoping asymmetry and is resolved by the user-id work above rather than a server-side patch.relationships create --user-idnow actually scopes the write. The CLI now forwardsuser_idto/create_relationship, and the API resolves it throughgetAuthenticatedUserId()instead of hard-coding the single-user UUID. This restores parity withrelationships list/delete/restoreand fixes cross-layer tenant-scoped relationship flows.ingestover tunneled client/server. The CLI no longer sends a client-sidefile_paththe server cannot read; remote transports carry the bytes in the request body.- Untracked
src/shared/openapi_types.tsdrift. Regenerated alongside everyopenapi.yamlchange; the contract-parity tests intests/contract/stay green. - Inspector payload completeness. Recent-conversation and relationship/entity-detail responses now include the metadata the UI previously had to re-derive or re-fetch, reducing follow-on queries and avoiding client-side schema-order duplication.
Tests and validation
- New regression tests:
tests/cli/cli_user_id_propagation.test.ts—NEOTOMA_USER_IDenv var, per-call--user-idflag override, and flag wiring across every read verb.tests/cli/cli_store_file_vs_entities_parity.test.ts—--filevs--entitiesproduce equivalent results for the same payload; second call with the same--idempotency-keyreturnsreplayed: trueon both paths; commit-mode stderr guard is wired onstoreandstore-structured.tests/integration/store_resolution_attributes_hint.test.ts—ERR_STORE_RESOLUTION_FAILEDincludes thehintwhen fields are nested underattributes; absent for unrelated unresolved-name cases.tests/cli/cli_ingest_remote_upload.test.ts—isLocalhostBaseUrlIPv4/IPv6/hostname coverage; auto-upload on non-localhost base URLs;--source-uploadforces upload regardless of transport; oversize abort before network I/O.tests/cli/cli_api_start_prod_advisory.test.ts— advisory text and install.md § reference present on both spawn branches; fires on--env prod + hasSource + childScript === dev:prod; background branch is guarded onoutputMode !== "json".
- Existing inspector/contract surfaces also ride the release:
openapi.yamlandsrc/shared/openapi_types.tsnow coverGET /recent_conversationsplus the entity/relationship enrichment fields used by inspector views. - Full CLI + integration test suite (444 tests) green on the patch branch.
Breaking changes
- None introduced in v0.5.1 itself. The patch retroactively documents the v0.5.0
attributes-nested-payload break (see Breaking change notice (retroactive to v0.5.0) above) and adds a structured upgrade hint, but the strict server behavior is unchanged.
Commits (v0.5.0 → v0.5.1)
a2d569bBump version to v0.5.13f0d9d9Pre-release: include v0.5.1 changes
Full compare: v0.5.0...v0.5.1
- /store payloads: entity fields must be at top level, not nested under 'attributes'
- Structured identity_basis in store responses
- Fuzzy duplicate detector (list_potential_duplicates)
- Ordered canonical_name_fields identity rules with fallback
Full changelog
[!IMPORTANT]
Breaking change for/storepayloads (v0.5.0): entity fields must be at the top level of each entity object. Callers that still nest fields underattributes(e.g.{ entity_type, attributes: { title, canonical_name, … } }) will seeERR_STORE_RESOLUTION_FAILEDwithERR_CANONICAL_NAME_UNRESOLVEDandseen_fields: ["attributes"].Fix: flatten your payload to
{ entity_type, title, canonical_name, … }. Starting in v0.5.1, the server response includes a structuredhinton the resolution issue explaining this exact remediation, and the CLI emits a stderr guard (warning: store returned entities_created=0 without replayed=true …) so silent failures no longer look like successes.See the
v0.5.1release notes for the full follow-up (attributes hint,replayed: trueflag,NEOTOMA_USER_IDenv-var propagation, systemd/prod runbook).
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.5.0 |
| Compare | v0.4.5 → v0.5.0 — view diff |
v0.5.0 strengthens entity identity end-to-end: every schema now declares how its entities are identified, every resolve reports a structured identity_basis, and a new read-only duplicate detector surfaces candidate pairs for operator review — while identity resolution itself stays deterministic and the entity hash is unchanged. The release also ships agent-shaped client helpers, MCP server-card introspection, new --since query filters, and site/install polish.
What changed for npm package users
CLI (neotoma, neotoma api start, …)
- New verb:
neotoma entities find-duplicates --entity-type <type> [--threshold N] [--limit N]. Read-only fuzzy duplicate scan; surfaces candidate pairs ranked by similarity withmatched_fieldsandscore. Confirm with the user, then hand off toneotoma request --operation mergeEntities. Never auto-merges. neotoma statsnow supports--by identity-basisto break observations down by how their entity's identity was resolved (schema_rule,heuristic_name,heuristic_fallback,target_id,schema_lookup). Dashboards and operators can now see how much of the graph is resting on strong-identifier rules versus heuristic fallbacks.neotoma entities listandneotoma observations listgain--since <timestamp>filters (maps toupdated_since/created_sinceon the query).neotoma doctorandneotoma mirrorget additional self-check and diagnostic paths;resolveBaseUrlrecords transport meta so transport choice is auditable across--api-only,--offline, and env flags.neotoma cli-instructions checkships a new Duplicate repair (on demand) atomic rule so agent clients (Cursor, Claude, Codex) know to call the detector, confirm, and only then merge.
Runtime / data layer
/register_schemanow requires schemas to declare eithercanonical_name_fields(ordered precedence list of single-field or composite rules) or an explicitidentity_opt_out: "heuristic_canonical_name"flag. For back-compat, the HTTP/CLI handler auto-injects the opt-out when neither is provided and logs a warning, so existing callers keep working. A startup log enumerates every schema currently relying on heuristic fallback.canonical_name_fieldsnow accepts ordered rules with partial-match fallback: the resolver walks the ordered list and uses the first rule whose fields are all present (R1). Flat arrays keep working unchanged.- Every resolve records a structured
identity_basis, which flows through the/storeresponse, the MCP tool response, and a newobservations_by_identity_basisaggregation on/stats. - New post-hoc fuzzy duplicate detector. Per-schema config via
duplicate_detection_fields(snapshot fields compared beyondcanonical_name) andduplicate_detection_threshold(similarity 0..1, default 0.85). Read-only; hands off to/entities/mergeonce an operator or agent confirms a pair. - Bundled schemas (
src/services/schema_definitions.ts) now declare identity explicitly: priority types (person,company,contact,email_message,transaction,file_asset, plustask,note,project,location) use realcanonical_name_fields; the long tail carriesidentity_opt_out: "heuristic_canonical_name"so the gap is visible rather than silent.
Shipped artifacts
openapi.yamland regeneratedsrc/shared/openapi_types.tsinclude the newGET /entities/duplicatesendpoint, extendedStats(observations_by_identity_basis), and extendedStoreStructuredResponse(identity_basis). New MCP toollist_potential_duplicatesis wired through tool definitions, server dispatch, andcontract_mappings.- New JavaScript client helpers in
packages/client:diagnose.ts,helpers.ts,turn_report.ts(plus exports fromindex.ts), aimed at turn-shaped agent workflows. Client README andpackage.jsonupdated accordingly.
API surface & contracts
- New MCP tool:
list_potential_duplicates(entity_type, threshold?, limit?, user_id?)— read-only; never auto-merges. - New OpenAPI endpoint:
GET /entities/duplicates?entity_type=…[&threshold=][&limit=][&user_id=]returning rankedcandidates[]withentity_a,entity_b,score,matched_fields,entity_type. - Extended response fields:
StoreStructuredResponsenow includes a structuredidentity_basisper resolved entity.Statsnow includesobservations_by_identity_basis: Record<IdentityBasis, number>.
- Query schema additions:
EntitiesQueryRequestSchemaandObservationsQueryRequestSchemaacceptupdated_since/created_since. - Schema definition vocabulary (additive):
canonical_name_fieldsrule-list form,identity_opt_out,duplicate_detection_fields,duplicate_detection_threshold. - New MCP server-card surface (
src/mcp_server_card.ts) introspectable by clients.
Behavior changes
- Agent clients that use
list_potential_duplicatesmust confirm candidate pairs with the user (or repair plan) before callingmerge_entities. The detector is strictly post-hoc and never runs during write-time identity resolution; write-time identity stays deterministic viaentity_type + canonical_name(hash unchanged). /register_schemapayloads that omit bothcanonical_name_fieldsandidentity_opt_outstill succeed but are logged (server-side warning) and appear under the "heuristic fallback" bucket inneotoma stats --by identity-basis. Operators should migrate these schemas to declared identity over time.identity_basisappears in/storeresponses, MCP tool responses, and stats. Agent clients can now tell, per observation, whether identity was derived from a schema rule or a heuristic — useful for auditing silent merges.- The ordered
canonical_name_fieldsform lets a schema express "preferemail; if absent,full_name; if absent,first_name + last_name" without changing how the hash is computed.
Docs site & CI / tooling
- New Duplicate repair (on demand) atomic rule in
docs/developer/mcp/instructions.md,docs/developer/cli_agent_instructions.md, and the sync anchor table(.cursor/rules/developer_agent_instructions_sync_rules.mdc), propagated byneotoma cli-instructions checkinto the user-level~/.cursor/rules,~/.claude/rules, and~/.codextargets. - New MCP tool description for
list_potential_duplicatesindocs/developer/mcp/tool_descriptions.yaml. docs/subsystems/entity_merge.mdSection 7 rewritten to document R5 duplicate detection (schema-driven config, CLI/MCP surfaces, read-only constraint).docs/developer/cli_reference.mdanddocs/subsystems/markdown_mirror.mdrefreshed.install.mdexpanded with additional onboarding guidance (+53 lines).- New integrations doc:
docs/integrations/smithery_external_url.md.
Internal changes
- Resolver rewrite:
src/services/entity_resolution.tsnow walks orderedcanonical_name_fieldsrules and attaches a structuredidentity_basisto everyResolverTrace. Canonical-name derivation exposes a traced form (deriveCanonicalNameFromFieldsWithTrace). - Schema registry validation in
src/services/schema_registry.tsenforces R2; a newlogIdentityOptOutsAtStartupmethod enumerates opt-outs at boot. - New service
src/services/duplicate_detection.tswithstringSimilarity(normalized Levenshtein, reusingsrc/normalize.ts'slevenshtein) andfindDuplicateCandidates. - MCP server (
src/server.ts) gains alistPotentialDuplicatesdispatch path. Tool definitions (src/tool_definitions.ts) add the schema; contract mappings (src/shared/contract_mappings.ts) tie the MCP tool tolistPotentialDuplicatesOpenAPI operationId and to the new CLI verb. src/services/snapshot_computation.ts,src/services/observation_storage.ts,src/services/entity_queries.ts, andsrc/shared/action_handlers/entity_identifier_handler.tsupdated to carryidentity_basisend-to-end.- Agent-shaped helpers:
src/services/recent_record_activity.tsfeeds the CLIrecent/ingestsurfaces;src/mcp_server_card.tsexposes a structured server card.
Fixes
- Site:
fix(site): clarify install/evaluate prompts and install page flowandfix(site): streamline permissions preflight for install and evaluate(shipped commits onmainsince v0.4.5). - Frontend illustration and site polish:
SitePageAlt,EntityGraphHero,MainApp,site/repo_info.json. - Canonical mirror and SQLite adapter: stability fixes in
src/services/canonical_mirror_git.tsandsrc/repositories/sqlite/sqlite_client.ts. - Schema registration back-compat default for
identity_opt_outprevents legacy CLI/HTTP flows from breaking after R2.
Tests and validation
- New unit tests:
tests/unit/duplicate_detection.test.ts(stringSimilarity; candidate discovery with schema-declared fields, merged-entity exclusion, per-call threshold override),tests/unit/mcp_server_card.test.ts,tests/unit/client_diagnose.test.ts,tests/unit/client_helpers.test.ts,tests/unit/client_turn_report.test.ts. - Updated integration and service tests:
tests/integration/dashboard_stats.test.tsassertsobservations_by_identity_basis;tests/services/entity_resolution.test.tscovers ordered-precedence andidentity_basisthreading;tests/services/schema_registry_incremental.test.tsand numeroustests/integration/mcp_*.test.tsfixtures updated for R2's mandatory identity declaration. - OpenAPI types regenerated via
npm run openapi:generateandtests/contract/openapi_schema.test.tscovers the new MCP-tool-to-operationId mapping.
Breaking changes
- Schema registration (softened): Schemas MUST declare
canonical_name_fieldsoridentity_opt_out. For existing callers, the/register_schemaHTTP/CLI handler injectsidentity_opt_out: "heuristic_canonical_name"as a back-compat default (with a warning log) — so no caller breaks at runtime. Operators should migrate schemas to explicit identity declarations over time;neotoma stats --by identity-basisand the startup opt-out log make the gap visible. - Entity hash: unchanged. Identity resolution remains deterministic
entity_type + canonical_name. No data migration is required.
Commits (v0.4.5 → v0.5.0)
a59834aBump version to v0.5.0bdf474cPre-release: include changes for v0.5.0deaab88fix(site): clarify install/evaluate prompts and install page flow444a076fix(site): streamline permissions preflight for install and evaluate
Full compare: v0.4.5...v0.5.0
- neotoma doctor for consolidated onboarding diagnostics
- neotoma setup --tool for idempotent harness configuration
- Deterministic markdown mirror and MEMORY.md export
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.4.5 |
| Compare | v0.4.4 → v0.4.5 — view diff |
This release turns Neotoma's onboarding into an install-first flow and adds the first reusable integration surface for hook-driven agents, alongside a deterministic markdown mirror and bounded MEMORY.md export.
What changed for npm package users
CLI (neotoma, neotoma api start, ...)
- Added
neotoma doctoras a consolidated onboarding/runtime diagnostic so agents can inspect install state, API state, MCP wiring, CLI instructions, permissions, and hook eligibility without falling back to ad-hoc shell introspection. - Added
neotoma setup --tool <tool>to collapse init, MCP config, CLI instruction sync, and permission-file updates into one idempotent command for supported harnesses. - Added
neotoma hooks <status|install|uninstall>so hook-based integrations can be offered as an explicit post-activation step instead of being mixed into baseline setup. - Added
neotoma mirror <enable|disable|rebuild|status>plus supporting edit / export flows for teams that want a filesystem view of Neotoma state.
Runtime / data layer
- Added a stable core operations surface in
src/core/operations.tsso embedded clients and hook packages can call Neotoma actions directly with typed wrappers instead of reimplementing MCP dispatch. - Added deterministic canonical markdown renderers plus a filesystem mirror subsystem that can regenerate entity, relationship, source, timeline, and schema views from SQLite and optionally keep bounded
MEMORY.mdexports in sync. - Added an HTTP markdown rendering path for entity snapshots and aligned MCP text responses around deterministic markdown / JSON output selection.
- Expanded supporting state-layer plumbing across entity resolution, schema registry, raw storage, snapshot computation, timeline events, and local transport so the new mirror / export / hook flows share the same deterministic backend.
Shipped artifacts
- The main package continues to ship the CLI / server bundle,
openapi.yaml, README, and skills, but now also exposes a clearer reusable code surface for embedded integrations through the package exports and core operations module. - The repository now includes first-party packages for TypeScript and Python clients plus hook / adapter integrations for Cursor, Claude Code, Codex, OpenCode, and the Claude Agent SDK; these are part of the release scope in the repo and docs, even where publishing of the individual packages is staged separately.
API surface & contracts
retrieve_entity_snapshotnow documents aformatselector (markdowndefault for MCP,jsonfor raw payload callers), making the KV-cache-stable text contract explicit in OpenAPI and action schemas.- The server now exposes deterministic entity markdown rendering over HTTP for inspector and export flows, reusing the same canonical renderer family as MCP and the mirror.
- CLI / MCP parity work expanded the public contract around onboarding and storage behavior so hook packages and direct clients can share the same store / retrieve semantics.
Behavior changes
- Agent-led install is now opinionated: inspect with
neotoma doctor --json, configure withneotoma setup --tool <tool> --yes, then move into activation rather than improvising repo-specific shell commands. - Hook integrations are explicitly positioned as an opt-in reliability floor after first value, while MCP remains the quality ceiling for deliberate, schema-typed writes.
- Users who enable the markdown mirror can inspect Neotoma state as deterministic files and optionally keep a bounded
MEMORY.mdexport synchronized for file-oriented agent harnesses.
Docs site & CI / tooling
- The install guide, MCP instructions, CLI instructions, CLI reference, README, and hook documentation were rewritten around the install-first / activation-first workflow.
- The docs site and integration pages were updated for Cursor, Codex, Claude Code, Claude Agent SDK, install preflight snippets, and the new alternate site / illustration surfaces.
- Repo metadata and site copy now reflect the new onboarding language, hook architecture, and mirror/export capabilities.
Internal changes
- Added reusable packages under
packages/for@neotoma/client,neotoma-client, hook installers, plugin manifests, and the Claude Agent SDK adapter. - Added new services for canonical markdown rendering, canonical mirror rebuilds, git-backed mirror history, batch correction, entity-type equivalence / guard logic, flat-packed detection, memory export, and schema reference linking.
- Added new CLI support modules for doctor, setup, permissions, hooks detection, and mirror commands, plus corresponding transport and action-layer updates.
Fixes
- Tightened CLI / MCP / local transport parity so install/setup and embedded client flows can reuse the same behavior instead of drifting between interfaces.
- Improved entity resolution, raw storage, timeline event handling, and snapshot computation in support of the new deterministic mirror / export paths.
- Clarified instruction and onboarding rules so agents stop relying on brittle shell inspection during installation and activation.
Tests and validation
- Added and expanded CLI tests for doctor/setup, mirror, memory export, edit commands, onboarding commands, and command coverage.
- Added service-level tests for canonical markdown, canonical mirror, git-backed mirror behavior, batch correction, entity-type equivalence / guards, schema reference linking, flat-packed detection, raw fragment isolation, and memory export.
- Expanded integration and regression coverage for CLI-to-MCP parity, local transport behavior, entity resolution, raw storage, timeline events, and observation provenance.
Breaking changes
- None expected for the public API or CLI command semantics.
- Ship constraints for execution: local backup artifacts (
*.backup.*), temporary SQLite recovery files under.tmp_wav_fix_data/, and unrelated submodule drift are not intended for the release commit set and must remain excluded before tagging.
Commits (v0.4.4 → v0.4.5)
e1946fbVersion bump to v0.4.5b18e5e3Pre-release: include pending changes for v0.4.5
Full compare: v0.4.4...v0.4.5
- Bundled operational frontend screens removed; marketing-first experience only
- OpenClaw plugin contract via openclaw.plugin.json
- Site narrowed to documentation and evaluation focus
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.4.3 |
| Compare | v0.4.2 → v0.4.3 — view diff |
Neotoma 0.4.3 combines the committed marketing-site refresh already on main with the current release-candidate worktree: a narrower marketing-first frontend, OpenClaw-oriented packaging and contract surface, slimmer server wiring, and updated release tooling that can preview the exact GitHub Release body before tagging.
What changed for npm package users
CLI and runtime
- Added OpenClaw-oriented packaging inputs and tool-definition entrypoints via
openclaw.plugin.json,src/openclaw_entry.ts, andsrc/tool_definitions.ts, plus contract coverage intests/contract/openclaw_plugin.test.ts. - Updated package and runtime scripts around MCP stdio startup and release-note rendering, including pre-tag GitHub Release preview support in
scripts/render_github_release_notes.ts.
Runtime / data layer
src/server.tsis substantially reduced, signaling a slimmer runtime surface and less bundled operational UI/server behavior in this release train.- MCP stdio helper scripts were updated to match the narrower runtime packaging.
Shipped artifacts
dist/, runtime entrypoints, and plugin-facing packaging inputs change with this release.- The site bundle and route metadata also change as part of the same release.
API surface & contracts
- The release adds OpenClaw plugin contract coverage and new tool-definition entrypoints, so operators integrating through plugin/tool metadata should recheck the packaged surface after upgrade.
- The server/runtime contraction in
src/server.tsmeans previously bundled HTTP or app-facing behavior should be treated as changed unless confirmed otherwise in final validation.
Behavior changes
- The committed
mainrange adds the marketing-site refresh, walkthrough-route SEO, and responsive evaluate-prompt layout updates. - The current release candidate removes a large set of in-repo operational frontend screens and helpers, shifting the shipped frontend toward a marketing/documentation-first experience rather than the prior app-style UI.
- New or expanded subpages around comparison, foundations, memory guarantees, memory models, false-closure risk, multi-agent state, trading, and OpenClaw positioning continue the evaluation-first site narrative.
Docs site & CI / tooling
- Updated release-process documentation and skills so
/releasepreviews the exact rendered GitHub Release Markdown body before tagging. - Refreshed README, determinism docs, release checklist material, route coverage docs, and product-positioning/supporting site metadata to match the current packaging and positioning direction.
Internal changes
- Removed many legacy Cursor/Claude release-skill aliases, publish skill copies, and operational frontend components that no longer fit the current repo shape.
- Reworked site structure and supporting content across
frontend/src/components,frontend/src/site, and related docs. - Updated the release-notes renderer to support pre-tag previews using a future tag with a chosen head ref.
Fixes
- The committed range includes responsive evaluate-prompt and mobile-copy improvements on the marketing site.
- Local release-tooling fixes ensure previewed GitHub Release notes use the correct previous-tag compare base even before the new tag exists.
Tests and validation
- Added or updated contract and utility coverage through
tests/contract/openclaw_plugin.test.tsandfrontend/src/utils/entity_display.test.ts. - Full release validation has not been run in this preview step; final tagging should re-run the normal release validation suite after the intended local commit set is finalized.
Breaking changes
- The frontend removes many previously bundled operational screens, auth/realtime helpers, search/entity/source/schema views, quick-entry dialogs, and related tests. Users relying on the in-repo app UI should expect a materially narrower shipped interface.
src/server.tsis heavily reduced; any consumers depending on previous bundled server behavior should validate routes and integrations before upgrading.- Ship constraints:
docs/privateis a protected path and must not be included in the public release commit.foundation,.claude/settings.local.json,.cursor/plans/, and other local-only or private paths should be explicitly reviewed before staging.
Commits (v0.4.2 → v0.4.3)
a34156ddocs(release): add v0.4.3 GitHub release supplement9cd526fchore(release): bump version to v0.4.33fd62ebrefactor(site): narrow public UI and add OpenClaw packaging3b41faffeat(site): responsive evaluate prompt layout and mobile copy tests8f9b587feat(site): marketing site refresh, docs, and walkthrough route SEO248b89dMerge dev into main for v0.4.2 released28bb9eMerge dev into main (marketing site updates)
Full compare: v0.4.2...v0.4.3
Minor fixes and improvements.
Full changelog
Install
npm publish for 0.4.2 is still pending registry authentication in this environment. Once published:
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.4.2 |
| Compare | v0.4.1 → v0.4.2 — view diff |
Shipped scope: Git tag v0.4.2 is at 68cb675 (Release v0.4.2). Narrative and release notes use range v0.4.1..v0.4.2.
Neotoma 0.4.2 is a patch release focused on MCP server startup reliability plus site/docs polish. It fixes the packaged MCP SDK import path by moving TypeScript module resolution to NodeNext, refreshes the FAQ/nav/SEO site surfaces, and syncs current agent-instruction docs.
What changed for package users
CLI and runtime
- Fixed MCP server startup so the packaged server resolves
@modelcontextprotocol/sdk/serverthrough packageexportsinstead of failing on a missingserver/index.jspath. - Updated
tsconfig.jsontomodule: NodeNextandmoduleResolution: NodeNextso the runtime import and type resolution agree. - Regenerated the packaged
dist/output for the0.4.2publish target.
Site and docs
- Extracted FAQ content into
frontend/src/site/faq_items.ts, simplifyingFaqPage.tsxand centralizing the content source. - Updated the site header nav, docs sidebar nav, path handling, SEO metadata, repo info, and related subpage wiring.
- Applied small copy and UX cleanup around the memory guarantees and FAQ flows.
Agent instructions and release prep
- Refreshed
docs/developer/cli_agent_instructions.mdanddocs/developer/mcp/instructions.md. - Included the current hooks-planning notes under
.cursor/plans/in the released scope.
Fixes
- Fixed
ERR_MODULE_NOT_FOUNDfor the MCP SDK server import during startup. - Fixed FAQ / docs-nav wiring and kept docs sidebar coverage aligned with the current route structure.
Tests and validation
- The release candidate passed the pre-commit gate used during release prep:
tsc --noEmit,eslint src --ext .ts,npm test,npm run test:e2e, andnpm run validate:doc-deps. - Focused rerun:
npx vitest run tests/unit/docs_sidebar_nav.test.ts.
Breaking changes
- None called out for
0.4.2.
Commits (v0.4.1 → v0.4.2)
68cb675Release v0.4.29e2e83bfix(site): hero spacing, install CTA classes, scroll banner meet link17a4d2cdocs(release): refresh v0.4.1 GitHub release notes and supplement5258b9ffix(site): keep record-types headline tail on one line
Full compare: v0.4.1...v0.4.2
- SQLite recovery helper (scripts/recover_sqlite_database.js)
- MCP entity type count parity
- Interactive homepage demo and product illustrations
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.4.1 |
| Compare | v0.4.0 → v0.4.1 — view diff |
Shipped scope: Git tag v0.4.1 is at 8081ee5 (Release v0.4.1: incremental deploy (marketing site)). Narrative and release-notes:render --tag v0.4.1 use range v0.4.0..v0.4.1.
Post-tag dev (not in the v0.4.1 tag): 5258b9f3 — fix(site): keep record-types headline tail on one line. Ship as v0.4.2 (or cherry-pick) if that fix should ride with npm/GitHub users on the same semver.
Neotoma 0.4.1 tightens the release-prep workflow, adds a safer SQLite recovery path for local installs, improves MCP/CLI contract parity around entity counts, ships FU-301 marketing-site refresh with incremental Pages deploy, syncs foundation commands into Claude Code skills, adds the writ submodule for WRIT benchmarking, and continues the evaluation-first site refresh with clearer product positioning, install guidance, and homepage demos.
What changed for npm package users
CLI and runtime
- Added a SQLite recovery helper for corrupted local databases via
scripts/recover_sqlite_database.js, plus npm script entry points such asrecover:dbandrecover:db:prod. The flow runsPRAGMA integrity_check, optionally uses SQLite.recover, and keeps recovery manual and non-destructive instead of auto-swapping the live DB. - Expanded CLI guidance and release-prep tooling around the canonical
/releaseworkflow so GitHub/npm releases are prepared from the real shipped scope, including committeddevwork, explicit uncommitted-change previews, and clearer compare-range handling. - Continued CLI/API/runtime refinement across
src/cli/index.ts,src/actions.ts, andsrc/server.ts, including the release-candidate stability fix that makes CLI tests use the shared test API server inNODE_ENV=testunless--offlineis explicitly requested.
Runtime / data layer
- Added MCP coverage for canonical entity counts by type, backed by dashboard stats, so entity-type totals align better across MCP responses, CLI expectations, and contract tests.
- Updated shared action schemas, contract mappings, and generated OpenAPI types alongside the runtime changes so packaged server behavior and documented surface area stay in sync.
Shipped artifacts
openapi.yamland the generateddist/output change with this release.- The public site bundle, localized static packs, and related assets also change as part of the same release train.
API surface & contracts
- The release range includes parity work for entity-count reporting, with new MCP integration coverage in
tests/integration/mcp_get_entity_type_counts.test.ts. openapi.yaml,openapi_actions.yaml,src/shared/action_schemas.ts,src/shared/contract_mappings.ts, andsrc/shared/openapi_types.tsall moved with this release, so API consumers should refresh generated clients if they track the spec closely.- This is still a compatibility-focused update, not a broad contract reset, but operators using MCP or OpenAPI-derived tooling should recheck entity-count and schema-oriented flows after upgrade.
Behavior changes
- The site continues the evaluation-first product path: evaluate fit before install, keep key routes such as Evaluate / Install / Architecture consistently reachable, and make the homepage work better as a guided narrative instead of a static landing page.
- The homepage now includes a richer interactive CLI demo, updated section flow, and better hash-synced navigation behavior for the current slide IDs.
- Install and configuration pages continue to steer users toward understanding onboarding and memory fit before jumping straight into setup steps.
Docs site & CI / tooling
- FU-301: Marketing site refresh, SEO, and v0.4.1 prep docs; incremental GitHub Pages deploy for the marketing site (
Release v0.4.1: incremental deploy). - Refreshed public positioning, ICP, and release-targeting material across
docs/foundation/,docs/icp/, and homepage design guidance. - Expanded the
evaluate_positioningskill and related reference material so release prep, positioning review, and site iteration share the same framework. - Kept site coverage current with Playwright updates for hash navigation and other homepage regressions, plus ongoing route/SEO/localization maintenance in the frontend site layer.
Internal changes
- Renamed the canonical release command to
/releasewhile keeping/create_releaseas a legacy alias, and updated synced command/rule/skill copies accordingly. - Emit foundation commands as Claude Code skills (
.claude/skills/<name>/SKILL.md), with Cursor skill sync when not sourced from foundation. - Added
writsubmodule (WRIT write-integrity benchmark). - Synced generated Cursor/Claude instruction surfaces with the updated release workflow, positioning material, and rule set.
- Added the focused test-only transport behavior in
src/cli/index.tsto remove flaky per-command local transport startup during CLI test runs.
Fixes
- Fixed the docs sidebar toggle path for
/evaluateand/install. - Fixed stale homepage section-hash expectations so the current section IDs are covered by Playwright again.
- Fixed several homepage polish issues in this release train, including intro edge-indicator alignment and dark-surface readability improvements that continued after
v0.4.0.
Tests and validation
- The committed
v0.4.1candidate passed the full pre-commit gate used during release prep:tsc --noEmit,eslint src --ext .ts,npm run lint:site-copy,npm test,npm run test:e2e,npm run validate:coverage,npm run check:pw-coverage, andnpm run validate:doc-deps. - Release prep also included focused reruns of the previously failing CLI correction test and the homepage hash-update Playwright test after the fixes landed.
- The
v0.4.1tag exists on8081ee5; re-runnpm run -s release-notes:render -- --tag v0.4.1after any tag movement before publishing or editing the GitHub Release.
Breaking changes
- None called out for
0.4.1.
Commits (v0.4.0 → v0.4.1)
80203f2Release v0.4.1: incremental deploy (marketing site)5a95524Merge dev into main for release v0.4.1 (marketing site)9c62ea4FU-301: Marketing site refresh, SEO, and v0.4.1 prep docs56d4b50chore: add writ submodule (WRIT write-integrity benchmark)2665395fix(claude): emit skills as .claude/skills//SKILL.md5e816a2Sync .cursor/skills into Claude skills when not in foundation8034a9bEmit all foundation commands as Claude Code skillse91cacdchore(release): prepare main-repo v0.4.1 candidatee3b99e5Dev: CLI/API contracts, site UI, docs, cursor rules, inspector submodule0da9e28docs(icp): refresh primary ICP, dev release targeting, general release criteria; anonymize evaluator PII in public docs; add private field_evidence submodule refe9ad210fix(site): allow docs sidebar toggle on /evaluate and /install513e2babuild(site): refresh prerendered export for v0.4.048d6396docs(release): refresh v0.4.0 supplement for final site fixes897a22cfix(site): improve dark-surface copy contrastf03869afix(site): align intro section edge indicatorsaf63f54chore: remove repo-root clutter (tracked branch-ports state, npm pack artifact)aee67c2docs: update foundation submodule for release guidance6ce245frefine evaluation-first site flow and public release notesf91f41bdocs(release): prepare v0.4.0 notes and versioningc3778e4Update marketing site navigation, scroll UX, analytics, and subpagesddc25a1fix: track DatabaseMemoryPage for Vite build (gitignore data* clash)4300731Update marketing site, repo metadata, SEO, analytics, and home IA7119cacdocs(site): ICP paths, marketing pages, workflows, and site export refresh5f1f004Add site marketing pages, markdown hub, and SEO dev tooling6738fb5chore(docs): bump docs/private submodule (Isaac CD trilogy + persona)1b29eadfeat(site): healthcare, gov, customer-ops, logistics verticals; private doc submoduleea333c2refine(site): vertical landing shell UX and agent-auth pagea6ad85afix(site): ship AgentAuthLandingPage and full-page segment for /agent-auth8fee422feat(site): vertical index + landings, marketing full-page shell1485d9fci(dev-pages): install Playwright Chromium before site prerender build9e1f86efeat(site): CRM/compliance verticals, timeline/schema, docs, scripts49edfe4Release v0.3.11: site, docs, MCP/ChatGPT integration2f395c6Prepare v0.3.10 patch release metadata.c213566fix seo title on basename-root detail pages7e1b865Install Playwright Chromium in Pages deploy workflow.d332c75Add build-time prerendering for GitHub Pages SEO.4056ea9Update install page content tweaks.c242922Update localized site loading and docs navigation refinements.bcc074dCommit outstanding docs, frontend, and generated site updates.54af605Fix docs UI icon wiring and guarantee table runtime regression.555377aMerge branch 'dev'77408abRecord local main-branch updates before merge.5f71e37Update docs site cards, icons, and integration walkthrough content.930f283Fix intermittent intro invisibility on dev homepage.3488aa2Fix blank home sections on dev site by relaxing fade-in visibility gating.a9237c0Update site content, navigation, and integration walkthrough pages on dev.6e7a63fRestore today's recovered site redesign and asset work after rebase loss, including new ICP/interface artwork and expanded landing subpages.ee2eb53Update site content and isolate dev Pages deployment.73bd182Fix dev site build by removing stale data-model route and fallback missing card images.f9fb20fReplace missing site illustration assets with stable fallback image.98a9f49Fix dev deploy lockfile mismatch and widen guarantees section.5b843ccUpdate site content and isolate dev Pages deployment.6a5007aOverhaul docs and site architecture for expanded multilingual navigation.401e560Revert GitHub Pages content to v0.3.8.99421d3Fix Playwright site coverage test startup.d6f0c46Release v0.3.9.81f1edaRelease v0.3.8.2b6377dFix CI install by removing local tarball self-dependency.ab79c46Merge branch 'release/v0.3.3'b07926fRelease v0.3.7.16e00b8Apply post-hook updates to CLI init and site build artifact.ba4ef5aUpdate CLI startup docs and environment handling.0b8b7b0Release v0.3.6.fb38a64Merge pull request #22 from markmhendrickson/release/v0.3.356c6c6fAdjust mobile table chrome and keep desktop table styling.2c3e0acMerge pull request #21 from markmhendrickson/release/v0.3.39105bb3Prepare v0.3.5 and fix get-started demo asset.a92e410Merge pull request #20 from markmhendrickson/release/v0.3.3c5444b2Release v0.3.5.7f791c9Release v0.3.4.9ed256bchore(frontend): normalize related post ordering9c03939Release v0.3.3.f2c42d0Release v0.3.2.666962cdocs: add tester checklist for init env fixes8def077fix(cli): init .env creation and clearer env/config status062669eFinalize site updates and deployment readiness.b3311cbRelease v0.3.1.7ef1b01Merge dev into main for release v0.3.130234c7Prepare v0.3.1 release inputs and deployment tooling.fff53dbInclude workflow note and CLI wrapping improvements in release.83e602aApply remaining CLI cleanup changes before release merge.9565b70Finalize CLI init flow updates for release branch.489c2f5Prepare v0.3.0 developer release with domain cutover.7f90811Fix GitHub Pages root 404; improve CLI session resize and box width66f9d72Ignore public/ build output; fix OAuth redirect and CLI box formatting8db5c36Fix GitHub Pages sidebar and styles; deploy build:ui; CLI and test fixes79d26cbDeploy site from dev branch; rename env.example to .env.example; tunnel script tweaks83a9c01Refactor auth workflows and align API contract coverage.fff77fcRefactor auth flows, CLI fallback, and site SEO updatesa246a6fRefactor rules, docs, CLI tests; fix tests and data-dir exclusions22a7209Add CLI-first agent parity, local entity embedding, and expanded test coverage72b72a0Add deletion/GDPR and entity snapshot embeddings; expand CLI and testsc6207a5Add timeline_events service and migrations; add user_id to interpretationsc60dbc9Update mcp/web-scraper submodule and doc table alignment56ff927Add crypto layer and log encryption; update docs and SQLite adapter9eb3877Create v0.3.0 reconciliation release and archive aspirational releasesb1e1f25Update CLI, migrations, and docs/UI alignment3296f35Consolidate cursor rules, expand design system docs, add snapshot monitoring4836f12Update docs/private submodule to latest commit after resolving conflictsf68ef4dMigrate generic development rules to foundation and add major implementation worka979409Refactor schema registry and entity queries with raw_fragments support4cef222Improve test quality, fix auto-enhancement bugs, optimize database16adc1aAdd parquet MCP resources specification35f3314Fix CI: Check migration files only, not database state1ba6598Update README and documentation, clean up frontend dependencies28fc875Update README with canonical vocabulary and ignore error reportse02e9d0Update v0.2.0 release status and refactor codebaseaa8210fReorganize documentation, update cursor rules, and add frontend components1d70f5eExecute v0.2.0: Minimal Ingestion + Correction Loopcccb77cFU-110: Implement v0.2.0 sources-first ingestion architectureffd87efFU-MIGRATION-001: Migrate cursor commands and rules to foundation systemb59501aExtract generic Cursor rules to foundation0a1f7cbUpdate agent instructions: add foundation submodule usagec44c8e4Update foundation: copyright year 20254df364cUpdate foundation submodule: README with license066b6f9Add foundation submodule with MIT Licensebda6e62Re-add foundation submodule with LICENSEe078d48Update foundation submodule to use GitHub remoted6066e1Complete foundation submodule setup9eb4a14Convert foundation to git submodulea711d60Convert foundation to git submodulec13e62eAdd foundation: shared development processes8732d0aFix database migration handling and improve error reportinga019979Separate dev/prod environment variables for securitya095922Enforce strict dev/prod Supabase environment separation6739dc3Reorganize documentation structure and update configuration7c0b443docs: Update documentation and add integration candidates3886150Remove credentials from notify_running_agents_credentials.js7f4b4bbAdd security check to validation checkliste9788b6Remove credential passing via API environment field3109c14Remove credentials from respawn_single_agent.js and add security prohibition0a56267Remove unused loadCredentials call from respawn script2fa97e1Remove credentials from agent instructions in respawn scriptccf55f6Update task instructions to require all tests passing before completion8c106e6Update orchestrator instructions to require all tests passing3cc555cUpdate setup script to automatically apply migrations via Management APIfae2af0Configure Cursor Cloud Agents environment.jsoncf79c84Update orchestrator for Cursor Cloud Agents Secrets4b5e954Update setup script to handle Supabase CLI authentication gracefully249bac0Add automated setup script for agent environments5c2a957fix: resolve blockers for cloud agent execution2a9e9b0Align v0.2.x+ release execution with orchestrator58fa448Align v0.x release docs and workflow069bacdStandardize string literals to double quotes228b320Refactor release documentation structure and fix syntax errors415dd5aFix doc inconsistencies: align with v0.2.0 minimal scope54c2b10Streamline release spacing: minimal core first, defer safety nets2190bcdv0.2.0: formalize nondeterminism boundary, harden validation, prioritize core flows80ce612Add v0.2.0 release plan and align docs with sources-first ingestionb8c95c2feat: payload ingestion and observation hardeningf907748Remove data symlink from git tracking8a67f29Fix retrieve_records order preservation and update documentation0670069Add entity and timeline MCP endpoints, enhance Cursor integration, and update documentationac2e2beComprehensive documentation and codebase updates2c1b61eComprehensive documentation and infrastructure updates4ee9a7bEnhance commit command with comprehensive change analysis229ea54Major documentation restructure and timeline estimate updates148e1fadocs: Comprehensive documentation, workflow, and release planning updates7ea05d8docs: Comprehensive documentation and workflow improvementscc8f67bfeat: restructure docs, add manifest, and refine frontend toolingb1bb143feat: Add AI-powered record comparison and enhance file upload insightsf8178f3Docs: restructure MVP docs and architecture overview Tests: stabilize UI integration against missing frontend/backend Chore: ignore local data and private docs; improve SSL debug scripts9b0181bfeat: add branch-based domain routing with HTTPS support1fc4d72Merge branch 'feat/playwright-coverage-worktree'701b40drefactor: migrate commit command to user-level058595bMerge remote-tracking branch 'origin/feat/playwright-100-percent-coverage' into feat/playwright-100-percent-coverage16a8484chore: harden commit workflow and dev serve helpers30a2051fix: stabilize ui tests0c9cf48feat: achieve 100% Playwright test coverage across functional, state, and component dimensions93050d7feat: achieve 100% Playwright test coverage across functional, state, and component dimensionsfa594c3Fix WebSocket port discovery and improve error handlingc3c6a42Merge branch 'fix-debug-issue-gpENr' into dev0d12f01feat: implement fuzzy matching for record searches and fix chat query discrepancies6cedbb2Merge remote-tracking branch 'origin/feat/playwright-test-coverage' into dev9a683d9feat: add comprehensive Playwright end-to-end test coveraged789da4Merge branch 'chat-20251118-140748-044d41' into devd9662cbtest(e2e): add Playwright harness and server fixtures514fbbachore(cursor): move commands and rules out of repo4277753feat(records): dynamic property columns and dev tooling3d8f694Align Plaid normalizer expectations with machine-case propsd1169b2feat: add worktree support to merge-dev scripteae2780feat: restore chat intro message, fix key change detection, and improve AI query behavior3b1b890Stabilize dev env tests and oauth state443e536feat: add connectors platform and modern records workspace3c4a01cfeat: align grooming tools and docs576ba04fix: improve error handling and API configuration for file uploadse75df73Merge branch 'test/convert-ui-integration-test-stubs' into dev644cceedocs: update merge command to switch to dev after merge45ecc14Merge branch 'test/convert-ui-integration-test-stubs' into dev3e9bf2dfeat: enhance file processing, error handling, and UI improvements367a99cMerge test/convert-ui-integration-test-stubs into dev8e18735chore: switch license from ISC to MIT809121atest: Convert UI integration test stubs to executable tests64421c0feat: Add summary field to records with AI-generated summaries1a73db1feat: Add merge command to merge current branch into dev16cab5afeat: Add chat-specific branch management with automatic renaming12d3fc5docs: improve commit command instructions to prevent missing changes8e4bca9feat: implement local-first end-to-end encrypted datastore architecture730ddeffeat: migrate UI to React with shadcnfabd232Update README with chat endpoint in API spec table751a1cfAdd chat interface with OpenAI function calling for record queries99150f9Add Plaid integration, API sandbox UI, and security logging improvements79285c8WIP: CSV uploader with normalization and LLM transformsdc11c6dInitial commit: MCP server for extensible record storage with semantic search, ChatGPT Actions, and Supabase backend
Full compare: v0.4.0...v0.4.1
- Evaluation-first site with clearer positioning
- Vertical landing pages (CRM, compliance, healthcare, logistics, government)
- Expanded timeline and snapshot behavior
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.4.0 |
| Compare | v0.3.10 → v0.4.0 — view diff |
Release summary: Neotoma 0.4.0 is the first npm release after 0.3.10, combining the unpublished v0.3.11 train with the current dev work. The headline is a clearer evaluation-first site, expanded vertical positioning, and a larger round of CLI/runtime/schema changes that justify a minor release instead of another patch.
What changed for npm package users
CLI and runtime
storage infois clearer and more script-friendly, with explicit environment context, absolute local paths, and a stronger nudge toward--jsonfor stable automation.- CLI argument handling is more reliable when Neotoma is invoked through node, bun, or deno wrappers. The
extractUserCliArgschange avoids accidental fallback into interactive session mode. - Timeline, observation projection, snapshot computation, schema registry, interpretation, and action schema work continue the push toward cleaner schema-aware behavior across the packaged server and CLI.
Why it matters
- Operators get a more dependable CLI surface for automation and debugging.
- Teams depending on timeline- and schema-heavy flows should expect more capable behavior, but should still validate those paths before rollout because the release range is broad.
Shipped artifacts
openapi.yamland the generateddist/output change with this release.- The release-prep toolchain now includes a better GitHub release renderer plus helper scripts for timeline health, timeline recomputation, and site copy linting.
API surface & contracts
- This release range includes meaningful changes around actions, timeline generation, schema behavior, and OpenAPI output.
- If the currently outstanding server/runtime work lands before tag, treat the HTTP and MCP contract surface as materially updated from
0.3.10and verify integrations accordingly. - If you consume Neotoma programmatically, plan on rechecking OpenAPI-driven clients and any assumptions about timeline event shape.
Behavior changes
- The website now pushes a clearer evaluation-first path: users are expected to evaluate fit before install or tool-specific setup.
- The docs and marketing surface expand further into vertical-specific entry points such as CRM, compliance, healthcare, government, logistics, and customer operations.
- Header navigation and related page flows are being simplified so key routes such as Evaluate, Install, and Architecture stay consistently reachable.
- Homepage polish continues in this release candidate: intro edge indicators now anchor to the true section bottom, and dark-surface supporting copy is easier to read across the FAQ, footer, and shared code-block treatments.
- If the remaining runtime refactors ship in this release, some server-side behavior may change even where the public surface area looks similar.
Docs site & CI / tooling
- The site adds more landing pages, more explicit product positioning, a markdown hub, and broader SEO/dev-preview support.
- GitHub Pages and Playwright coverage continue to expand so site regressions are caught earlier.
- The static export pipeline and route/site validation scripts are being tightened as part of the same train.
- Repo documentation is being reorganized, including ICP material moving into a clearer
docs/icp/home.
Internal changes
- This release train includes broader refactoring across
src/server.ts,src/actions.ts, andsrc/cli/index.ts. - The current
devwork also removes the olderllm_extractionpath and reshapes related tests and docs. - Test coverage is being updated to reflect navigation, schema, MCP, and CLI changes, including the new header-navigation assertion and targeted site regressions for intro layout and dark-surface readability added during release prep.
- Repo-root cleanup also landed in the release branch so tracked branch-port state and old local pack artifacts do not ride along with future public release prep.
Fixes
- The known
AgentAuthLandingPage//agent-authVite build regression was fixed. - Navigation and section-flow cleanup continues across the site experience.
- Additional site fixes now keep hero edge indicators visually aligned and improve muted-text contrast on dark surfaces.
- The release-prep flow itself is now better documented for skipped npm versions, so GitHub release compare ranges can match the real npm upgrade path.
Tests and validation
- Release prep has already passed typecheck, lint, site copy lint, unit/integration suites, Playwright site coverage, Playwright coverage validation, and doc dependency validation for the committed release-prep changes.
- The final public-release candidate also passed the same pre-commit gate after adding focused Playwright checks for intro-section layout, themed code-block backgrounds, and footer label contrast.
- Before tagging
v0.4.0, run the full release checks against the final committed tree:npm run build:server,npm test, and any route/site-export validation needed for the final site content. - If the remaining outstanding runtime work is included, validate CLI workflows, MCP/OpenAPI consumers, and timeline behavior against real data before publish.
Breaking changes
- The upgrade path is effectively
0.3.10 -> 0.4.0becausev0.3.11never shipped to npm. - The currently intended scope includes semver-significant work: removal of the old
llm_extractionpath, larger server/action refactors, and OpenAPI churn. That is why this release is being prepared as minor0.4.0rather than a patch. - For users coming from
0.3.10, also review the unpublishedv0.3.11narrative because its CLI and runtime changes are expected to land in the same next npm release.
Commits (v0.3.10 → v0.4.0)
65d0bc6build(site): refresh prerendered export for v0.4.01c355b9docs(release): refresh v0.4.0 supplement for final site fixes5df815bfix(site): improve dark-surface copy contrast7dddd47fix(site): align intro section edge indicators14174f8chore: remove repo-root clutter (tracked branch-ports state, npm pack artifact)1048479docs: update foundation submodule for release guidance2ffbff0refine evaluation-first site flow and public release notes55b5df2docs(release): prepare v0.4.0 notes and versioning6db15c5Update marketing site navigation, scroll UX, analytics, and subpages5aaf17ffix: track DatabaseMemoryPage for Vite build (gitignore data* clash)fe5900cUpdate marketing site, repo metadata, SEO, analytics, and home IAaa7bccadocs(site): ICP paths, marketing pages, workflows, and site export refresh715673dAdd site marketing pages, markdown hub, and SEO dev tooling675c70achore(docs): bump docs/private submodule (Isaac CD trilogy + persona)9e6c0e1feat(site): healthcare, gov, customer-ops, logistics verticals; private doc submoduled818180refine(site): vertical landing shell UX and agent-auth pagea1ae104fix(site): ship AgentAuthLandingPage and full-page segment for /agent-authdddd291feat(site): vertical index + landings, marketing full-page shelld0a268aci(dev-pages): install Playwright Chromium before site prerender build649003cfeat(site): CRM/compliance verticals, timeline/schema, docs, scriptsaf9be62Release v0.3.11: site, docs, MCP/ChatGPT integration
Full compare: v0.3.10...v0.4.0
- neotoma entities search with improved query handling
- neotoma storage merge-db with conflict modes
- ChatGPT Apps and Custom GPT integration documentation
Full changelog
Install
npm install -g [email protected]
| | |
|:--|:--|
| npm | https://www.npmjs.com/package/neotoma/v/0.3.11 |
| Compare | v0.3.10 → v0.3.11 — view diff |
Patch release: npm 0.3.11, large CLI + HTTP action + MCP runtime hardening, instruction / OpenAPI alignment, plus the docs site and ChatGPT / MCP integration pages. The single release commit bundles prior work on retrieval parity, entity query paths, and agent-facing rules—not “docs only.”
What changed for npm package users
CLI (neotoma)
entities search: positional identifier,--identifier, and compatibility alias--query(documented indocs/developer/cli_reference.md); MCP/CLI parity called out there and in MCP instructions.store: preferred structured input--entities/--file; legacy--json=<payload>remains as an alias for structured entities (still use--json=with no space for reliable shells). Bare--jsonstays the global JSON output flag.storage merge-db: merge SQLite DBs with--source/--target, conflict modessafe(default) |keep-target|keep-source,--dry-run, optional--no-recompute-snapshots. Documented in CLI reference.sync_mcp_configsscript and related config wiring updated for current MCP layouts.
HTTP Actions / in-process API (dist/)
- Substantial updates to
src/actions.tsand shared handlers: entity listing/query behavior, schema/action plumbing, and alignment with MCP-facing flows. Consumers of the packaged server/API binary pick this up viadist/.
Retrieval & entities
entity_queries,entity_handlers,entity_identifier_handler, and related server paths: broader query/identifier handling and regression coverage (including lexical search integration tests). Aims at more reliable list vs identifier-style queries and parity with MCP expectations.
MCP server runtime (dist/)
server.tsand related services (MCP OAuth, oauth key gate, local entity embedding edge cases, etc.) updated alongside the action layer. MCP clients using the published package get the new behavior from the built server.
Bundled OpenAPI (npm tarball)
openapi.yamlshipped in the packagefileslist is updated this release.
Repository-only (not in the npm files list)
openapi_actions.yaml— OpenAPI-shaped surface oriented toward Custom GPT / HTTP Actions workflows; clone or copy from the repo when you need it. The npm package still shipsopenapi.yamlonly unlesspackage.jsonfilesis expanded later.
Agent / instruction sources (repo + sync workflows)
docs/developer/mcp/instructions.md— expanded MCP interaction block: prod vs neotoma-dev default, retrieval query-shape guidance, publication-recency vs observation recency, relationship batching instore,create_relationship+ EMBEDS clarification, external-tool and research deliverable store-first rules, entity-type consistency for imports, CLI parity (search/storealiases), CLI backup transport (--api-only/--base-url) when reconciling with MCP.docs/developer/cli_agent_instructions.md— same prod vs dev default, publication recency semantics for “recently published” style prompts.docs/developer/cli_reference.md— documents the flags above,storage merge-db, and MCP/CLI parity notes.docs/developer/mcp_overview.md— batchedstore+relationshipsexample;mcp_chatgpt_setup.md— points ChatGPT Apps connector readers tochatgpt_apps_setup.md.- These files are what
sync_mcp_configs/ rule-copy flows use; refresh local rules after pull if you rely on generated.cursor/ MCP instruction payloads.
API surface & contracts
src/shared/action_schemas.tsandopenapi.yamlevolved together with the action handlers.- New
docs/developer/chatgpt_integration_instructions.mdand related ChatGPT/MCP setup docs for connector and Custom GPT paths.
Docs site & CI / tooling
- Integration subpages (per-product connect flows), ICP copy, multilingual site generation,
validate:locales, GitHub Pages workflow (Playwright Chromium, path filters), Playwright site / 404 specs. docs/releases/in_progress/v0.3.11/release tracking; foundation submodule doc nits.
Breaking changes
- None called out;
storage merge-dbdefaults tosafemode to avoid silent data loss—call that out to operators merging databases.
Commits (v0.3.10 → v0.3.11)
af9be62Release v0.3.11: site, docs, MCP/ChatGPT integration
Full compare: v0.3.10...v0.3.11
Minor fixes and improvements.
Full changelog
Incremental patch release. Includes CLI and data-layer runtime improvements alongside docs/site updates.
What changed for npm package users
CLI (neotoma api start)
- The CLI now detects whether it is running from a full source checkout or a global/normal npm install. When source scripts are not present, it starts the built API server directly instead of attempting dev/watch scripts that would fail.
- Tunnel mode (
--tunnel) is gated behind source-checkout detection with a clear error message when unavailable.
SQLite adapter (local_db_adapter)
- Refactored for clarity and maintainability; behavior is equivalent but internal structure changed. Matching test updates included.
README
- Substantially revised; the updated version ships in the npm tarball.
API surface
openapi.yamlis unchanged in this release.
What changed for the docs site and tooling
- Overhauled docs navigation and multilingual site architecture.
- Fixed several UI regressions: docs icon wiring, homepage intro fade-in visibility, missing/fallback illustration assets.
- Added build-time prerendering and Playwright Chromium install for GitHub Pages SEO.
- Updated integration walkthrough content, install page copy, and localized page loading.
- Refreshed agent rules/skills and release/deploy workflow support files.
Commits (v0.3.9 → v0.3.10)
0f38c88Prepare v0.3.10 patch release metadata.79bae79Fix SEO title on basename-root detail pages.030a79bInstall Playwright Chromium in Pages deploy workflow.dbafcfbAdd build-time prerendering for GitHub Pages SEO.e20fc6fUpdate install page content.66aaa5fUpdate localized site loading and docs navigation.7883f03Commit outstanding docs, frontend, and generated site updates.1443b2aFix docs UI icon wiring and guarantee table runtime regression.25c0f10Merge branch 'dev'.b7fd822Record local main-branch updates before merge.10e2006Update docs site cards, icons, and integration walkthrough content.eeecda3Fix intermittent intro invisibility on dev homepage.b8c1a08Fix blank home sections on dev site by relaxing fade-in visibility gating.73d833eUpdate site content, navigation, and integration walkthrough pages on dev.ae9c3c8Restore site redesign/assets and expanded landing subpages after rebase recovery.68316d7Update site content and isolate dev Pages deployment.cf98425Fix dev site build by removing stale route and fallback missing card images.d30938bReplace missing site illustration assets with stable fallback image.e3bafd0Fix dev deploy lockfile mismatch and widen guarantees section.7af1b3eUpdate site content and isolate dev Pages deployment.bccfb9cOverhaul docs and site architecture for expanded multilingual navigation.c03f8f8Revert GitHub Pages content to v0.3.8.
Full diff: v0.3.9...v0.3.10
- Updated homepage content structure, navigation, and sidebar behavior
- Expanded CLI init configuration with environment-targeting support and stronger config path handling
- Added developer docs for onboarding, installation, Docker usage, and memory failure modes
Full changelog
Highlights
- Ships a refreshed site and not-found experience, including updated homepage content structure and navigation/sidebar behavior.
- Expands CLI init configuration and environment-targeting support, plus stronger config path handling.
- Adds new developer docs for onboarding, installation, Docker usage, and memory failure modes/interactions.
Testing and Reliability
- Adds/updates targeted CLI, config, site-data, and Playwright tests for the new behavior.
- Stabilizes Playwright site coverage startup by aligning fixture UI startup with the configured Playwright base URL port.
Included Commits
- c966806
Release v0.3.9. - ec99f96
Fix Playwright site coverage test startup.
Minor fixes and improvements.
Full changelog
Highlights
- Fix npm package install resilience by shipping
openapi.yamland introducing shared OpenAPI file resolution that works outside source checkouts. - Keep MCP stdio streams safe by moving schema registry informational logs off stdout.
- Improve CLI init context detection for package-consumer projects using installed
neotomain the current working directory. - Add release-safety contract coverage for package contents and stdio logging behavior, plus integration adjustments for credential-related unstructured store edge cases.
- Include minor UI polish for section navigation tooltips in the sidebar.
Validation
vitestsuite executed via pre-commit hooks during release commit.- Targeted contract and regression tests passed locally, including OpenAPI install resilience and stdio logging safety.
Improved CLI startup behavior across local workflows.
Full changelog
Patch release focused on CLI startup behavior, onboarding guidance, and site/update alignment.
Highlights
- Improved CLI startup and environment handling behavior across local workflows.
- Added and updated onboarding documentation to better guide first-run agent setup.
- Applied post-hook CLI/init test updates and refreshed generated site output artifacts.
Documentation updates
- Expanded developer-facing setup and onboarding docs, including CLI configuration guidance and onboarding flow documentation.
- Refined MCP/CLI instruction docs and related getting-started/release checklist material.
Included commits
013f097— Release v0.3.7.ac5e363— Apply post-hook updates to CLI init and site build artifact.9dc73b2— Update CLI startup docs and environment handling.
Notes
- GitHub release tag:
v0.3.7 - Release branch target:
release/v0.3.3
- No manual migration steps required for typical installs.
- If you use custom CLI initialization flows, review updated init behavior and CLI docs.
- Improves mobile table rendering while preserving desktop styling.
- Expands CLI initialization behavior and startup UX coverage.
- Adds VM testing documentation (macOS) and refreshes setup/release docs.
Full changelog
Highlights
- Improves mobile table rendering while preserving desktop table styling.
- Expands CLI initialization behavior and startup UX coverage.
- Adds VM testing documentation and refreshes setup/release docs.
Key Changes
- Frontend: updates table and site page behavior for mobile layout polish (
frontend/src/components/SitePage.tsx,frontend/src/components/ui/table-scroll-wrapper.tsx). - CLI/Core: substantial updates in CLI command flow and MCP config scanning (
src/cli/index.ts,src/cli/mcp_config_scan.ts,src/cli/config.ts). - Tests: adds and updates init/session tests to validate init targeting and interactive flows (
tests/cli/cli_init_commands.test.ts,tests/cli/cli_init_interactive.test.ts,tests/cli/cli_session_startup_ux.test.ts). - Docs: updates developer docs and adds
docs/developer/macos_vm_testing.md. - Assets: includes demo asset
frontend/src/assets/thinking-and-planning-demo.gif.
Upgrade Notes
- No manual migration steps required for typical installs.
- If you use custom CLI initialization flows, review updated init behavior and CLI docs.
Full Changelog
https://github.com/markmhendrickson/neotoma/compare/v0.3.5...v0.3.6
- Refreshed get-started docs flow with unified tool-agnostic walkthrough and single screen recording
- Improved docs table UX (full‑width, rounded borders, mobile handling, scroll hints)
- Updated Docker runtime documentation for CLI and MCP usage
Full changelog
Highlights
- Refresh docs site get-started flow with a unified tool-agnostic walkthrough and single clickable screen recording.
- Improve docs table UX and visual consistency (full-width tables, rounded borders, mobile behavior, scroll hint logic).
- Update Docker packaging/runtime docs and snippets for CLI + MCP usage from containerized deployments.
Validation
- Passed: npx vitest run src/site/site_data.test.ts
- Passed via pre-commit hooks: type-check, lint, tests, e2e, docs dependency validation.
Fixed pagination and total count inconsistency for deleted tasks.
Full changelog
Highlights
- Fix
retrieve_entitiesforentity_type: \"task\"to paginate after deleted-entity filtering. - Align
totalwith visible (non-deleted) entities so pagination offsets remain consistent. - Add regression coverage for task pagination/count consistency.
Included changes
src/services/entity_queries.tssrc/shared/action_handlers/entity_handlers.tstests/integration/mcp_entity_variations.test.ts
Minor fixes and improvements.
Full changelog
What Changed
CLI reliability for npm-installed usage
- Added fallback Neotoma path resolution from the installed CLI location so commands work from arbitrary working directories.
- Updated CLI repo/path resolution flow to better support shells where no source-checkout cwd is present.
Terminology and UX clarity
- Reworded user-facing CLI messaging to distinguish:
Neotoma path(configured runtime path)Neotoma source checkout/root(source-required workflows)
- Removed ambiguous "repo" phrasing in prompts, status panels, and error guidance where it confused npm-installed users.
Docs alignment
- Updated CLI and runbook documentation to match the new terminology.
- Updated init/env troubleshooting/test instructions so expected output strings match current CLI behavior.
Frontend/content updates
- Included current in-branch frontend content updates already staged in this release.
- Normalized related-post ordering in site data and added a targeted assertion in frontend tests.
Behavior Changes
neotomacommands that depend on path resolution behave more reliably when run outside a source checkout, including VM/remote shell contexts.- User guidance now refers to "Neotoma path" and "source checkout" instead of generic "repo" wording.
Internal Changes
- Added/updated CLI tests to reflect updated path-resolution behavior.
- Added frontend assertion to guard related-post ordering expectations.
Fixes
- Fixed path-resolution failures that could surface as setup/init guidance even after install in non-repo working directories.
Tests and Validation
- Pre-commit validation suite passed for both commits on
release/v0.3.3. - Ran frontend tests:
npm run test:frontend.
Breaking Changes
- None identified.
Deployment Note
- This release is created from
release/v0.3.3branch. GitHub Pages deploy workflow remains untouched because no push tomainwas performed.
Minor fixes and improvements.
Full changelog
What Changed
CLI and Initialization Reliability
- Fixed
neotoma initbehavior to correctly create.envwhen repo context is established later in the flow, including runs launched outside the repo. - Improved no-command CLI guidance and environment/configuration status messaging in
src/cli/index.ts. - Added explicit tester guidance for this fix set in
docs/testing-instructions-init-env-fix.md.
Site and Documentation Delivery
- Updated site content/SEO and generated docs/site assets:
frontend/src/components/SitePage.tsxfrontend/src/site/site_data.tsfrontend/src/site/seo_metadata.tsfrontend/index.htmlfrontend/docs.htmlscripts/build_github_pages_site.tsxdocs/assets/neotoma_banner.png
Runtime and Service Hardening
- Applied small but broad service/runtime updates across API and MCP-related modules:
src/actions.ts,src/server.ts,src/mcp_ws_bridge.tssrc/services/mcp_auth.ts,src/services/mcp_oauth.tssrc/services/field_validation.ts,src/services/field_converters.tssrc/services/parquet_reader.ts,src/services/public_key_registry.tssrc/crypto/auth.ts
Packaging and Release Hygiene
- Updated package metadata/version state in
package.jsonandpackage-lock.json. - Updated release/deployment docs and status artifacts.
Behavior Changes
neotoma initnow more reliably creates and reports.envsetup outcomes.- Running
neotomawithout command/context provides clearer actionable guidance for missing repo/env configuration.
Internal Changes
- Refined site build and deployment-related content generation.
- Included supporting documentation and release/process cleanup tied to these fixes.
Fixes
- Resolved
.envcreation edge case during interactive init. - Improved env/config status visibility in CLI initialization output.
Tests and Validation
- Added a dedicated tester checklist for init/env behavior verification.
- Updated related docs and release validation references.
Breaking Changes
- None identified.
- Enhanced CLI initialization and startup behavior
- Release safety checks and process guidance
- Release infrastructure tooling for Cloudflare and publish validation
Full changelog
What Changed
CLI and Setup
- Improved CLI initialization and startup behavior in
src/cli/index.ts, including richer setup/status handling used duringneotoma initand startup flows. - Expanded environment defaults in
.env.exampleto better align local setup with current runtime expectations.
Frontend and App Boot
- Updated frontend boot wiring in
frontend/src/main.tsxandfrontend/src/components/MainApp.tsx. - Added analytics utility support in
frontend/src/utils/analytics.tsand related typings infrontend/src/vite-env.d.ts.
Release and Infrastructure Tooling
- Added release safety checks and process guidance in
docs/developer/pre_release_checklist.md. - Added release/deployment helper scripts for Cloudflare and publish validation:
scripts/check_bundlephobia.jsscripts/cloudflare_ensure_caa_letsencrypt.shscripts/cloudflare_set_dns_only.shscripts/cloudflare_set_github_pages_apex.shscripts/remove_cloudflare_redirect.sh
- Updated deployment guidance in
docs/infrastructure/deployment.md.
Packaging and Dependency State
- Updated
package.jsonandpackage-lock.jsonfor release packaging and dependency alignment. - Updated rule-distribution copies for CLI instructions (
.cursor,.claude,.codex).
Behavior Changes
neotomastartup and initialization paths are more explicit and consistent during first-run configuration.- Frontend bootstrap and telemetry integration behavior were updated for site/app runtime.
Internal Changes
- Strengthened pre-release and deployment process assets to reduce release risk and improve repeatability.
- Added supporting shell tooling for DNS/domain and release health workflows.
Fixes
- Setup and startup edge cases in CLI initialization flow were addressed.
Tests and Validation
- Maintained CLI command coverage guard updates in
tests/cli/cli_command_coverage_guard.test.ts. - Added pre-release validation checks and publish quality guardrails.
Breaking Changes
- None identified.
- Canonical domain moved to neotoma.io
- GitHub Pages deployment from main branch
Full changelog
Highlights
- Developer release focused on production domain cutover and release operations.
- GitHub Pages deployment switches from
devtomain. - Canonical site URLs move from
https://markmhendrickson.github.io/neotoma/tohttps://neotoma.io. - Release preflight is green on type-check, build, tests, and install simulation.
Full functionality audit summary
- API surface: OpenAPI currently contains 61 path entries.
- CLI surface: includes auth, store/upload, entities, sources, observations, relationships, timeline, schemas, stats, snapshots, request passthrough, and MCP setup flows.
- MCP surface: includes store/retrieve/query/mutate actions for entities, observations, relationships, schemas, interpretations, and auth.
- Web/docs surface: static site includes install, terminology, API/MCP/CLI capability tables, and setup guidance.
- Storage/runtime surface: local SQLite-first flow, source file storage, backup/logging commands, and API server runtime controls.
Changes in this release
Infra and deployment
- Pages workflow trigger changed to
main. - Deployment guide updated for
mainpublishing and directneotoma.ioserving. - Cloudflare redirect-removal checklist added for apex cutover.
- Developer workflow doc includes guidance to disable Cursor commit attribution trailer.
- CLI output wrapping now prefers path and word boundaries for cleaner terminal formatting.
Domain reference migration
- Replaced all
https://markmhendrickson.github.io/neotoma/references withhttps://neotoma.ioin:- frontend site metadata
- frontend/public/site_pages
index.html - robots/sitemap files
- SEO unit tests
Tests and verification
tests/unit/seo_metadata.test.tspasses with updated canonical domain.- Full test suite pass: 89 test files passed, 2 skipped; 1054 tests passed, 12 skipped.
npm run simulate:installpasses end-to-end.
Breaking/operational changes
- Marketing site deployment source branch is now
main. - Canonical domain references now target
https://neotoma.io. - Cloudflare forwarding to GitHub Pages URL must be removed to avoid redirect loops/mixed canonical behavior.
Known blockers before final cut
npm whoamicurrently returns401 Unauthorized, so npm publish cannot run until registry auth is configured.- External infrastructure tasks (Cloudflare rules + GitHub Pages custom-domain enforcement) require dashboard access and confirmation.
Release sequence after approval
- Confirm this version and notes.
- Fix npm auth, publish
v0.3.0. - Merge
devtomain. - Verify Pages deploy from
main. - Tag
v0.3.0and create GitHub release.