Skip to content

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

No immediate action
v0.15.0 Breaking risk

pull_request type, grant extensions, issue‑submission fix

Upgrade now
v0.14.0 Breaking risk
Auth Breaking upgrade RBAC

Tenant isolation + search improvements

Review required
v0.13.0 Breaking risk
Crypto / TLS Breaking upgrade

Agent instructions + CLI changes + Plan entities

Review required
v0.12.1 Breaking risk
Auth

Guest token validation hardens

Review required
v0.12.0 Breaking risk
Auth Breaking upgrade

Reporter env required for submit_issue

Upgrade now
v0.11.1 Breaking risk

Auth bypass fix

v0.11.0 Breaking risk
⚠ Upgrade required
  • 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.
Breaking changes
  • `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.
Notable features
  • 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.1v0.11.0view 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 store operation for structured entities, file-backed sources, or both. Legacy store_structured and store_unstructured references should move to store.
  • Interpretation provenance is explicit. Store requests can include an interpretation block, and agents can create interpretation runs for existing sources with create_interpretation.
  • Lower-friction MCP setup for npm users. neotoma mcp config defaults 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 /mcp proxy 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> --yes remains the recommended greenfield command. It runs idempotent init, MCP config, CLI instruction setup, hooks/plugins where supported, and permission-file patches.
  • neotoma mcp config now defaults to transport preset B. Packaged npm installs launch Neotoma directly over stdio for local MCP clients; no neotoma api start is required for the default MCP path.
  • --mcp-transport a remains available for signed AAuth HTTP /mcp proxy entries. Use it when the dev/prod API is already running and trusted attribution is more important than lowest setup friction.
  • --mcp-transport d writes signed prod-parity entries where both MCP slots point at prod HTTP /mcp.
  • neotoma setup documentation now lists every setup flag, including --install-scope, permission --scope, --rewrite-neotoma-mcp, --skip-hooks, --all-harnesses, --dry-run, and --skip-permissions.
  • neotoma processes adds a development/ops helper for listing and terminating Neotoma-related local processes.
  • neotoma instructions print and /mcp-interaction-instructions expose the shipped MCP interaction instructions without requiring agents to inspect repo files.

Runtime / data layer

  • POST /store is the canonical operation for structured and file-backed writes.
  • POST /interpretations/create creates interpretation rows for agent-extracted entities from an existing source.
  • store requests can include interpretation provenance 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_structured and store_unstructured; use store.
  • Deprecated store aliases still map to store in internal contract mappings where compatibility is needed.

Inspector

  • Added feedback admin unlock flow, including CLI challenge redemption and the Inspector /feedback/admin-unlock page.
  • 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 store instead of store_structured.
  • Regenerated static site_pages/ output is included in this release.

API surface & contracts

  • POST /store operationId is now store (was storeStructured).
  • POST /store/unstructured is removed. Send file-only or file+entity payloads to POST /store instead.
  • Store request schemas include optional interpretation provenance.
  • Store responses may include interpretation_id for observations produced through an interpretation run.
  • Added schemas: InterpretationConfig, StoreInterpretationInput, CreateInterpretationRequest, and CreateInterpretationResponse.
  • Added path: POST /interpretations/create.
  • listInterpretations is 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 a or d and run a reachable HTTP API.
  • Site and agent-facing examples use store as the canonical tool name.
  • Existing stored data is not migrated.

Agent-facing instruction changes

  • MCP and CLI instructions center the canonical store tool.
  • 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> --yes and the read-only mcp guide / cli guide surfaces instead of ad hoc shell introspection.

Plugin / hooks / SDK changes

  • Cursor hook reminders and compliance detection now recognize canonical store calls 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 /mcp when 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 setup flag surface and structured setup report.
  • README and install docs align on neotoma setup as 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-port chooses 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 --noEmit
  • npx vitest run tests/contract/ --reporter=verbose
  • npx vitest run tests/cli/cli_command_coverage_guard.test.ts --reporter=verbose
  • npm run openapi:bc-diff
  • npm run build:server
  • npm pack --dry-run

Breaking changes

  • POST /store operationId changed from storeStructured to store. Codegen clients that referenced operations.storeStructured must switch to operations.store.
  • POST /store/unstructured was removed. Use POST /store with file_content + mime_type or file_path for file-only writes.
  • MCP tools store_structured and store_unstructured are no longer canonical. Agents and clients should call store.
  • CLI commands neotoma store-structured and neotoma store-unstructured are removed. Use neotoma store with --entities, --file, or --file-path.
  • Default MCP transport changed from signed proxy preset A to local stdio preset B. Users who require signed HTTP /mcp attribution must pass --mcp-transport a or --mcp-transport d.

Commits (v0.10.1v0.11.0)

  • 9df225c chore: advance inspector for v0.11.0
  • 53e238f chore: finalize v0.11.0 release

Full compare: v0.10.1...v0.11.0

v0.10.1 Breaking risk

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.0v0.10.1view diff |

This hotfix preserves user-registered entity schemas when their type name overlaps a built-in alias.

Highlights

  • Keep custom schemas authoritative. store_structured and interpretation now check active DB-registered schemas before applying built-in aliases such as organization -> 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_type before applying code-defined aliases. A user-registered organization schema therefore validates as organization instead of being remapped to the built-in company schema.
  • 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_structured callers 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/global organization schema when one exists.
  • The built-in company alias for organization remains available as a fallback for users who have not registered a separate organization schema.
  • 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) before resolveEntityTypeFromAlias(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 organization schema could be bypassed because the built-in company schema declares organization as an alias. The regression caused fields outside the built-in company schema, such as slug, sector, location, and custom relationship fields, to land in raw_fragments.

Tests and validation

  • npx vitest run tests/services/schema_definitions.test.ts --reporter=verbose
  • npx vitest run tests/services/entity_resolution.test.ts --reporter=verbose
  • npx vitest run tests/integration/store_registered_schema_alias_precedence.test.ts --reporter=verbose
  • npx vitest run tests/contract/ --reporter=verbose

Breaking changes

No breaking changes.


Commits (v0.10.0v0.10.1)

  • 8789b9d Merge branch 'hotfix/v0.10.1'
  • 107dc91 Bump version to v0.10.1
  • 95cc8be fix(store): preserve registered schema type precedence
  • 63022f3 docs(site): smooth agent storage guidance copy
  • 7046532 docs(site): clarify storage guidance and API startup
  • c7f9af6 docs(release): move v0.10.0 GitHub supplement to completed

Full compare: v0.10.0...v0.10.1

v0.10.0 Breaking risk
⚠ Upgrade required
  • `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.
Breaking changes
  • 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.
Security fixes
  • Token expiry enforcement prevents use of expired access tokens that previously passed validation.
Notable features
  • `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.1v0.10.0view 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/token endpoint now accepts grant_type=refresh_token, and the mcp_oauth service 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, and experimental.session.compacting are 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/token now accepts grant_type=refresh_token alongside authorization_code. A valid refresh_token returns a fresh access_token (and optionally a rotated refresh_token) without requiring the user to re-authorize through the browser flow.
  • getAccessTokenForConnection refreshes against the upstream auth provider when a stored access token expires, persisting the new token and (if rotated) the new refresh token in mcp_oauth_connections.
  • validateTokenAndGetConnectionId now checks access_token_expires_at and returns a tokenRefreshFailed error for expired tokens instead of silently succeeding. Both local-backend and remote-backend paths enforce this check.
  • New refreshAccessToken export 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: new refresh_token grant 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: validateTokenAndGetConnectionId now 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: new checkpoint_management, post_build_testing, release_detection, release_status_readme_update rules; image_generation and process_feedback skill removed; publish skill added; create_release and release skills updated for the v0.10.0 workflow.

Plugin / hooks / SDK changes

@neotoma/opencode-plugin

  • Adopts the OpenCode v2 hook API: event() dispatches session.created, session.compacted, and message.updated events; tool.execute.after replaces tool.called; experimental.session.compacting injects 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.user hook now stores a conversation entity alongside the user conversation_message in a single store call with an inline PART_OF relationship, matching the canonical store recipe.
  • New NeotomaClientLike interface and client option enable test-seam injection without a live server.
  • cwd option and NEOTOMA_HOOK_STATE_DIR env 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.json gains keywords, author, repository, homepage, and bugs fields for npm discoverability.
  • README rewritten with npm-package install path ("plugin": ["@neotoma/opencode-plugin"] in opencode.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: IronClawIcon and OpenCodeIcon SVG 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.md added.
  • 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 from docs/specs/ to docs/releases/archived/mvp_planning/.

Internal changes

  • Foundation submodule updated from 14442cbd to f3c5c53 (store-neotoma skill, plan_sections_rules, draft-illustration skill, release workflow refinements).
  • .claude/ rules and skills synced with foundation: rules modernized, setup_symlinks skill removed in favor of setup_cursor_copies, publish skill added.
  • .cursor/ skills synced: create-release and draft-illustration updated 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, and WhoProfileCardVisual frontend components added/updated (committed in 36efc6e3).
  • conversation/v1.3.json schema snapshot added.

Fixes

  • Expired token passthrough: validateTokenAndGetConnectionId previously returned connection info for expired access tokens without checking access_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_OF relationship to the conversation entity in a single store call, preventing orphaned conversation_message entities.

Tests and validation

  • tests/integration/mcp_oauth_token_endpoint.test.ts — integration tests for the refresh_token grant type on the /oauth/token endpoint.
  • 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_at are now rejected by validateTokenAndGetConnectionId. Previously these would silently succeed. MCP clients should handle the tokenRefreshFailed error by refreshing via the new refresh_token grant 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.1v0.10.0)

  • 5c8e7d0 Merge dev into main for v0.10.0
  • 6c2fd50 Bump version to v0.10.0
  • 39a5f9d Pre-release: include pending changes for v0.10.0
  • 36efc6e feat(agent): add compliance eval and hook enforcement updates

Full compare: v0.9.1...v0.10.0

v0.9.1 Breaking risk

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.0v0.9.1view 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 check now uses mcpsrv_neotoma_dev and mcpsrv_neotoma in claude_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_widget while the server still accepts the legacy neotoma://ui/timeline_widget URI for compatibility.

What changed for npm package users

CLI (neotoma mcp check)

  • Claude Desktop config installs now write mcpsrv_neotoma_dev and mcpsrv_neotoma keys instead of neotoma-dev and neotoma.
  • Existing Claude Desktop configs that still use neotoma-dev or neotoma are reported as repairable issues, and the fixer migrates those keys to the compliant mcpsrv_* IDs.
  • neotoma uninstall recognizes the new Claude Desktop mcpsrv_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 after npm 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_widget so older clients do not break.

Behavior changes

  • Claude Desktop users should no longer see server-ID validation failures caused by neotoma or neotoma-dev keys 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.ts
    • npm run type-check
    • npm run build:server
    • npm run openapi:bc-diff
    • npm pack --dry-run

Breaking changes

No breaking changes.


Commits (v0.9.0v0.9.1)

  • 3614fac fix(mcp): Claude Desktop mcpsrv_* IDs and ui:// timeline widget
  • f8d67aa fix(ci): unblock GitHub Pages deploy and CI after v0.9.0

Full compare: v0.9.0...v0.9.1

v0.9.0 Breaking risk
Notable features
  • 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.0v0.9.0view 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 start now serves the Inspector SPA at /inspector out of the box — no separate build, no NEOTOMA_INSPECTOR_STATIC_DIR, no Docker flag. Operators can disable, relocate, or point at an external Inspector via six new NEOTOMA_INSPECTOR_* env vars.
  • Every hook harness reports per-turn telemetry to a single conversation_turn entity. cursor-hooks, opencode-plugin, claude-code-plugin, codex-hooks, and claude-agent-sdk-adapter all accrete onto one conversation_turn keyed 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 legacy turn_compliance entity is preserved as an alias.
  • Run the full feedback pipeline locally with zero hosted config. submit_feedback now mirrors every submission into a neotoma_feedback entity in the local DB. Inspector /feedback, neotoma triage, and the ingest cron all work end-to-end on a fresh install. Set NEOTOMA_FEEDBACK_ADMIN_MODE=disabled to 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 start now serves the Inspector at /inspector by default. The bundled SPA is baked into dist/inspector/ at publish time via prepublishOnly. No env vars required for the default path.
  • neotoma triage --set-status and --resolve now mirror triage changes onto the neotoma_feedback entity via mirrorLocalFeedbackToEntity, keeping the JSON store and entity graph in sync.
  • tsc --watch --preserveWatchOutput replaces bare tsc --watch in all watch/dev scripts and the CLI's internal api start spawner, eliminating the terminal-clearing behavior that made concurrent output unreadable.

Runtime / data layer

  • New inspector_mount.ts service handles the Inspector SPA lifecycle: bundled-first (from dist/inspector/), fallback to NEOTOMA_INSPECTOR_STATIC_DIR, or external URL via NEOTOMA_PUBLIC_INSPECTOR_URL. Live-build mode (NEOTOMA_INSPECTOR_LIVE_BUILD=1) re-reads index.html on each request and injects a 2-second poll for watch workflows.
  • cookie-parser added as a runtime dependency for sandbox session management.
  • sandbox_sessions table added to SQLite schema with bearer-token-hash, one-time-code-hash, pack selection, and expiry tracking. local_auth_users gains is_ephemeral column for session-scoped users.
  • New conversation_turn seeded schema (160 lines) in schema_definitions.ts with aliases turn_compliance and turn_activity, composite canonical-name identity [session_id, turn_id], and reject collision policy. Includes instruction_diagnostics (classification, confidence, reason, signals, recommended_repairs) and followup_message fields for compliance diagnosis.
  • New listConversationTurns and getConversationTurn service functions.
  • listRecentConversations service updated.
  • MCP_INTERACTION_INSTRUCTIONS_FALLBACK constant exported from server.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) with NEOTOMA_FEEDBACK_ADMIN_MODE env var. GET /admin/feedback/preflight now returns mode and mode_env. Local-mode routes read/write the JSON store and mirror to entity graph.
  • mirrorLocalFeedbackToEntity (src/services/feedback/mirror_local_to_entity.ts) and storedFeedbackToEntity projection (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 package files list. The Inspector SPA is built during prepublishOnly.
  • openapi.yamlneotoma_env field added to the /mcp/config response schema.

API surface & contracts

  • GET /admin/feedback/preflight response now includes mode: "hosted" | "local" | "disabled" and mode_env: "NEOTOMA_FEEDBACK_ADMIN_MODE" alongside the existing configured boolean.
  • GET /admin/feedback/pending in local mode returns records from LocalFeedbackStore with mode: "local" in the response body.
  • POST /admin/feedback/:id/status in local mode writes the JSON record and mirrors to neotoma_feedback entity. All admin routes still require hardware / software / operator_attested AAuth tier.
  • GET /mcp/config response now includes neotoma_env (resolved NEOTOMA_ENV for 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 /inspector by default on every neotoma api start. The root landing page links to it. Previously required NEOTOMA_INSPECTOR_STATIC_DIR and a separate build step.
  • Unconfigured feedback installs default to local mode instead of returning 501 admin_proxy_unconfigured. The 501 is now reserved for NEOTOMA_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:full and watch:full:prod now include a concurrent Inspector watcher with live-build mode, plus a dev:resources:watch lane showing local resource URLs.
  • pack:local now includes build:inspector so 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_FALLBACK is a compact, structured fallback covering the critical turn lifecycle, store recipes, display rule, and retry policy. Agents connecting to a Neotoma server where docs/developer/mcp/instructions.md is unreadable (packaged app, broken path) receive this compact block instead of the old unstructured fallback. The compact block is tested by tests/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.ts hook: 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 drops additional_context from this hook; reminders use sessionStart and postToolUse instead.)
  • New post_tool_use_failure.ts: captures tool_invocation_failure entities for Neotoma-relevant tools, bumps per-(tool, error_class) counter on disk.
  • after_tool_use.ts (renamed from postToolUse in docs): tool_invocation observation, optional small-model reminder, failure-hint surfacing.
  • stop.ts: conversation_message safety net, compliance backfill with bounded root-cause classification (instruction_diagnostics, diagnosis_confidence, recommended_repairs), classifier-driven followup_message for non-compliant turns.
  • _common.ts: per-turn state management (NEOTOMA_HOOK_STATE_DIR), failure-signal accumulator with PII scrub, error classification, small-model detection, isExpectedNetworkError downgrade, ConversationTurnObservationInput type, accreteTurn helper.
  • 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_turn accretion via recordConversationTurn from @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_failure entity storage. One-shot hint via user_prompt_submit additional 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).
  • notify and session_end hooks updated for turn telemetry.

claude-agent-sdk-adapter (TypeScript, +372 lines)

  • Same TS failure-signal infrastructure. recordConversationTurn from @neotoma/client.
  • UserPromptSubmit hook surfaces one-shot failure hint.

@neotoma/client

  • New helpers.ts exports: ConversationTurnInput interface and recordConversationTurn helper 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. New InstallCodeBlock component.
  • "Verticals" → "Use Cases": VerticalsIndexPage / VerticalIconTile / VerticalLandingShell deleted; replaced by UseCasesIndexPage / UseCaseIconTile / UseCaseLandingShell.
  • GitHub Pages build: Asset paths normalized to root-absolute /assets/… everywhere (fixes broken chunk URLs on nested routes). New finalizeBundledAssetPathsInAllHtml pass and validate_site_export.ts checks.
  • pick-port.js: New --print-resources flag displays local resource URLs (Inspector, MCP, API, UI) alongside port allocation.
  • show-dev-resources.js: New script (and dev:resources / dev:resources:watch npm scripts) that prints a summary of local dev resource URLs.
  • watch:full / watch:full:prod: Now include Inspector watcher (watch:inspector) and dev:resources:watch as concurrent lanes; NEOTOMA_INSPECTOR_LIVE_BUILD=1 set automatically.
  • New eval:tier1 / eval:tier1:update: npm scripts for the Tier 1 agentic eval harness.
  • --preserveWatchOutput added to all tsc --watch invocations across npm scripts and CLI internals.

Internal changes

  • cookie-parser dependency added for sandbox session cookie handling.
  • Dockerfile simplified: Inspector is always built (no BUILD_INSPECTOR arg), served at /inspector from dist/inspector/. VITE_NEOTOMA_API_URL and VITE_PUBLIC_BASE_PATH build args removed.
  • fly.sandbox.toml cleaned up: BUILD_INSPECTOR, VITE_NEOTOMA_API_URL, VITE_PUBLIC_BASE_PATH, NEOTOMA_INSPECTOR_STATIC_DIR, NEOTOMA_INSPECTOR_BASE_PATH removed.
  • 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 via inspector_mount.ts.
  • New sandbox service files: pack_registry.ts, seeder.ts, sessions.ts under src/services/sandbox/.

Fixes

  • GitHub Pages nested-route asset paths fixed (root-absolute /assets/… instead of relative ../assets/).
  • tsc --watch terminal clearing eliminated across all dev workflows via --preserveWatchOutput.
  • Feedback admin proxy no longer returns 501 on unconfigured installs; defaults to local mode.

Tests and validation

  • tests/integration/feedback_admin_proxy.test.ts — extended with tri-state mode resolver, preflight mode/mode_env fields, 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 new conversation_turn schema.

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.0v0.9.0)

  • 3f24c4d Bump version to 0.9.0
  • de411ee Pre-release: include pending changes for v0.9.0
  • b0e7c19 fix(ci): unblock v0.8.0 GitHub Pages deploy

Full compare: v0.8.0...v0.9.0

v0.8.0 Breaking risk
Breaking changes
  • NEOTOMA_AGENT_CAPABILITIES_* env vars removed; migrate with 'neotoma agents grants import'
  • agent_grant entity type replaces committed agent_capabilities.default.json
Security fixes
  • Hardware attestation verification (Apple Secure Enclave, WebAuthn-packed, TPM 2.0)
  • Attestation revocation lookup (OCSP, CRL) prevents revoked agents from writing
Notable features
  • 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.1v0.8.0view 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

  • hardware tier now means hardware, on every supported platform. Algorithm-only promotion is gone. The hardware tier requires a verified cnf.attestation envelope 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 committed config/agent_capabilities.default.json registry are removed in favour of agent_grant entities managed in the Inspector under "Agents → Agent grants" or via standard MCP / REST entity-store calls. A new neotoma 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_attested tier between software and hardware. Verified-AAuth callers whose iss, sub, or iss::sub pair appears on the operator allowlist are surfaced as operator_attested (rank 3). Configured via NEOTOMA_OPERATOR_ATTESTED_ISSUERS and NEOTOMA_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-packed leaves, and OCSP / CRL for tpm2 AIK chains now demote revoked agents from hardware (or operator_attested) to software with failure_reason: "revoked". Operators that need an audit window can opt in to NEOTOMA_AAUTH_REVOCATION_MODE=log_only or disabled. 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_id inside isSandboxMode() (via ensureSandboxAauthUser), 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_grant admission 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 the assertCanWriteProtected guard. 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_grant entity type is registered in src/services/schema_definitions.ts. No table migration is required (the entity is stored in the existing entity / observation infrastructure). The legacy attribution_tier column accepts the new operator_attested value; 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) and tpm_attestation_roots/ (Infineon, STMicro, Intel, AMD bundles, each with sourcing notes and SHA-256 fingerprints). Operators can supplement or replace either set via NEOTOMA_AAUTH_ATTESTATION_CA_PATH.
  • Revocation is enforce by default. Operators that want to audit before flipping should set NEOTOMA_AAUTH_REVOCATION_MODE=log_only ahead of upgrading, observe attribution_decision log lines for revocation.status: "revoked" with revocation.demoted: false, and only then drop the override.
  • The NEOTOMA_AGENT_CAPABILITIES_* env vars and config/agent_capabilities.default.json are removed. Setting any of those variables causes startup to fail with a structured error. There is no in-place compatibility shim — operators MUST run neotoma 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.ts adds "operator_attested" to AttributionTier; algorithmLooksHardwareBacked is deprecated and no longer participates in tier derivation. New AttestationRevocationDiagnosticsField carries the revocation sub-object inside the decision diagnostics shape.
  • src/services/attribution_policy.ts adds operator_attested to parseMinTier and TIER_RANK (rank 3, between software and hardware).
  • src/services/agent_capabilities.ts extends default_deny to operator_attested for parity with software. 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.ts and src/services/recent_record_activity.ts recognize operator_attested in their KNOWN_TIERS lists.
  • src/services/session_info.ts ranks operator_attested as 3 and hardware as 4 and threads the revocation field through the /session response.
  • src/services/feedback/admin_proxy.ts recognizes operator_attested in its tier checks.
  • src/middleware/aauth_verify.ts walks the new resolution cascade (attestation → operator allowlist → signature → clientInfo → anonymous) and populates the extended attribution.decision diagnostics. attestationOutcomeForDiagnostics maps verifier output (including the new revocation field) into the request-scoped AttributionDecisionDiagnostics.

Attestation services

  • New: src/services/aauth_attestation_verifier.ts — format-dispatching entry point. Defines AttestationFormat, AttestationFailureReason (including "revoked"), AttestationOutcome (including the optional revocation field), AttestationEnvelope, and AttestationContext. New applyRevocationPolicy() helper centralises how revocation results affect tier resolution per RevocationMode and failOpen setting.
  • New: src/services/aauth_attestation_apple_se.ts — verifies Apple App Attestation chains against the bundled Apple App Attestation Root CA, derives the challenge from iat + cnf.jwk thumbprint, and binds the leaf's authenticated public key to the JWT's cnf.jwk thumbprint.
  • New: src/services/aauth_attestation_webauthn_packed.ts — verifies the W3C WebAuthn §8.2 packed-format statement. Parses alg / sig / x5c / optional AAGUID-from-cert-extension (OID 1.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 to cnf.jwk via RFC 7638 thumbprint. AAGUID admission honours NEOTOMA_AAUTH_AAGUID_TRUST_LIST_PATH.
  • New: src/services/aauth_attestation_tpm2.ts — parses the WebAuthn tpm statement (ver, alg, x5c, sig, certInfo, pubArea), walks the AIK chain to a trusted TPM CA root, verifies the signature over certInfo, and binds pubArea's public key to cnf.jwk via RFC 7638 thumbprint.
  • New: src/services/aauth_tpm_structures.ts — internal parseTpmsAttest() and parseTpmtPublic() 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 from NEOTOMA_AAUTH_ATTESTATION_CA_PATH; loads the optional AAGUID trust list from NEOTOMA_AAUTH_AAGUID_TRUST_LIST_PATH.
  • New: src/services/aauth_operator_allowlist.ts — implements the operator_attested lookup against NEOTOMA_OPERATOR_ATTESTED_ISSUERS and NEOTOMA_OPERATOR_ATTESTED_SUBS.
  • New: src/services/aauth_attestation_revocation.ts — defines RevocationMode, RevocationStatus, RevocationSource, RevocationOutcome, RevocationCheckContext, and RevocationFetcher. Implements checkRevocation() (entry point), checkAppleRevocation() (Apple endpoint), and checkOcspWithCrlFallback() 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 the agent_grant entity type. CRUD helpers, validation, and an in-memory cache for identity → grant lookups. Status transitions (activesuspendedactiverevoked) 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; otherwise sub alone.
  • New: src/services/aauth_admission.ts — maps a verified AAuth identity to a Neotoma agent_grant and returns an admission decision for downstream middleware. Records last_used_at observations for grants. Surfaces an AAuthAdmissionContext that 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. Exposes assertCanWriteProtected() and assertCanWriteProtectedBatch().
  • New: src/middleware/aauth_admission.ts — HTTP middleware that runs after aauth_verify, resolves the verified identity to a grant via aauth_admission, and writes the result onto the request context.
  • New: src/cli/agents_grants_import.ts — implementation of the neotoma agents grants import command. Reads NEOTOMA_AGENT_CAPABILITIES_JSON, NEOTOMA_AGENT_CAPABILITIES_FILE, or config/agent_capabilities.default.json and writes the equivalent agent_grant entities. Idempotent on (match_sub, match_iss, match_thumbprint).
  • New: registered agent_grant entity in src/services/schema_definitions.ts with canonical_name_fields ordered thumbprint > (sub, iss) > sub, last-write-wins reducer policies for all mutable fields, and name_collision_policy: "merge" so re-imports upsert.
  • src/services/observation_storage.ts and src/services/correction.ts now route every createObservation and createCorrection call through assertCanWriteProtected({ entity_type, op, identity, admission }). Out-of-scope writes return a structured 403 with code: "protected_entity_write_denied".
  • src/services/request_context.ts extends RequestContext with aauthAdmission?: AAuthAdmissionContext | null and exports getCurrentAAuthAdmission(). Absent on requests that did not pass through admission (unsigned local stdio, public discovery routes).
  • src/actions.ts registers admission middleware on every authenticated write route and adds the /agents/grants* REST surface (see API section).
  • src/server.ts is wired to the admission middleware and the new admission failure mappers.

CLI signer and four hardware backends

  • src/cli/aauth_signer.ts:
    • SignerBackend extended from "software" to "software" | "apple-secure-enclave" | "tpm2" | "windows-tbs" | "yubikey".
    • generateAndStoreKeypair({ hardware: true }) dispatches to the platform-appropriate backend (darwinaauth-mac-se, Linux → aauth-tpm2, Windows → aauth-win-tbs; --backend yubikey overrides 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.
    • mintCliAgentTokenJwt manually constructs and signs JWTs for hardware backends (DER ECDSA → JOSE r||s); software backend continues via jose.SignJWT.
    • buildAttestationEnvelope returns the platform-appropriate envelope: apple-secure-enclave on macOS, tpm (WebAuthn) on Linux and Windows, webauthn-packed on YubiKey. Challenge derivation (iat + cnf.jwk thumbprint) is identical across backends.
    • cliSignedFetch / seSignedFetch perform 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).
    • describeConfiguredSigner returns backend, se_key_tag / tpm2_handle_persistent_path / cng_key_name / yubikey_serial (whichever applies), hardware_supported, and hardware_supported_reason. neotoma auth session surfaces this in both JSON and text output. hardware_supported_reason no 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 over Security.framework. Exposes isSupported, 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 PIV YKPIV_INS_ATTEST instruction. Same surface. Build inputs: libykcs11 (Yubico), node-gyp, C++17. Picks the YubiKey via PKCS#11 slot enumeration; tracks the active key by yubikey_serial so 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 legacy NEOTOMA_AGENT_CAPABILITIES_JSON / NEOTOMA_AGENT_CAPABILITIES_FILE / config/agent_capabilities.default.json registries into agent_grant entities owned by the supplied user. Idempotent on (match_sub, match_iss, match_thumbprint). JSON-mode and human-readable summaries supported.
  • neotoma auth keygen --hardware works on macOS, Linux (with libtss2 + a TPM 2.0 device), and Windows (with TBS service running and a TPM). --backend yubikey is supported on any platform with libykcs11 and an inserted YubiKey.
  • neotoma auth session reports honest hardware_supported / hardware_supported_reason per platform and surfaces yubikey_serial when the active signer is YubiKey-backed.
  • New CLI subcommands neotoma aauth tbs-attestation, neotoma aauth tpm2-attestation, neotoma aauth yubikey-attestation (under src/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, and DetailPage.tsx are 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. New InspectorPreview component replaces the prior single-page Inspector demo.
  • New PrimitiveRecordTypePage exposes the canonical record-type primitives (entity, entity snapshot, observation, interpretation, relationship, source, timeline event) at /primitives with cross-links to their subsystem docs.
  • The agent-detail badge tooltip and a new AttestationEnvelopePanel render envelope-aware fields (format, AAGUID truncated, key_binding_matches_cnf_jwk, chain summary by CN + issuer, revocation status with source). tierIcon() covers all four tiers; operator_attested no longer falls through to the default glyph.
  • frontend/src/site/site_data.ts, seo_metadata.ts, repo_info.json, and doc_icons.tsx are updated for the new navigation, SEO entries, and icon set. frontend/src/index.css and tsconfig.json are touched for the new route layouts.

API surface & contracts

Agent grants (new)

openapi.yaml adds the following routes under /agents/grants:

  • GET /agents/grantslistAgentGrants. List grants for the authenticated user.
  • POST /agents/grantscreateAgentGrant. 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}/suspendsuspendAgentGrant. Move activesuspended.
  • POST /agents/grants/{id}/revokerevokeAgentGrant. Move active or suspendedrevoked. Terminal.
  • POST /agents/grants/{id}/restorerestoreAgentGrant. Move suspendedactive. 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? }. The revocation sub-object is omitted (not null) when NEOTOMA_AAUTH_REVOCATION_MODE=disabled, so operators can distinguish "we never checked" from "we checked and got good". 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.json returns a dereferenceable jwks_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 same agent_iss + agent_sub resolve to the same sandbox user_id even 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 hardware now render as software unless they ship a verified cnf.attestation envelope OR are placed on the operator allowlist (in which case they render as operator_attested).
  • NEOTOMA_MIN_ATTRIBUTION_TIER=hardware is now strictly stricter than in v0.7.x — pre-attestation agents that previously satisfied this gate will be rejected with ATTRIBUTION_REQUIRED until they upgrade. Operators rolling forward should consider min_tier=operator_attested (admits the operator allowlist + hardware) or min_tier=software during the migration window.
  • Revoked attestation keys demote from hardware (or operator_attested) to software with failure_reason: "revoked" by default. attribution.decision.attestation.revocation.demoted is true for the affected requests. Operators that need a soak window can set NEOTOMA_AAUTH_REVOCATION_MODE=log_only ahead of upgrading.
  • NEOTOMA_AGENT_CAPABILITIES_* env vars (or the legacy config/agent_capabilities.default.json registry) on a v0.8.0 process cause startup to fail with a structured error message pointing at neotoma agents grants import. Re-runs of the import are idempotent on (match_sub, match_iss, match_thumbprint).
  • Verification latency on log_only and enforce modes 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_decision log lines and a new attestation_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-limited attestation_demoted reason=revoked source=<…> agent_iss=<…> agent_sub=<…> line is emitted per-fingerprint when revocation actually demotes a request under enforce.
  • Sandbox AAuth callers now resolve to a stable user_id across 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.ts now accepts a verified AAuth signature whose identity matches an active agent_grant and resolves the request to that grant's owner user_id even 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 with AUTH_REQUIRED outside Sandbox.

Agent-facing instruction changes (ship to every client)

  • docs/developer/mcp/instructions.md and docs/developer/cli_agent_instructions.md are rewritten under the four-tier cascade. The Preferred — AAuth clauses describe four tiers and cnf.attestation. The MCP Preflight your session rule documents the extended attribution.decision shape including attestation (with revocation) and operator_allowlist_source. Setup docs flag that adding a new MCP server entry to .cursor/mcp.json requires reloading Cursor before its in-app MCP tools (including CallMcpTool) pick up the new server.
  • AGENTS.md cross-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.md
    • docs/subsystems/entity_snapshots.md
    • docs/subsystems/interpretations.md
    • docs/subsystems/timeline_events.md
  • docs/foundation/timeline_events.md is 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 + enforce migration plan), docs/subsystems/aauth_cli_attestation.md (Apple SE, Linux TPM 2.0, Windows TBS, YubiKey keygen flows; signer.json schema; 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 /session shape, new env vars, expanded diagnostics checklist, updated CLI signer section. Now also documents the per-agent capability scoping lifecycle through agent_grant entities 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, and docs/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 under tests/.
  • src/services/aauth_attestation_verifier.ts is the single module other verifiers route through; format-specific verifiers do not duplicate trust-config or applyRevocationPolicy() logic.
  • The aauth_admission middleware composes with the existing aauth_verify middleware; admission state propagates to the write path through request_context rather than module-level globals.
  • frontend/tsconfig.json and frontend/tsconfig.tsbuildinfo are 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 for operator_attested; the four-tier visual cascade now matches the four-tier semantic cascade.
  • attribution.decision surfaces enough information to debug attestation failures and revocation outcomes without enabling debug logging.
  • eligible_for_trusted_writes reflects the resolved tier honestly under the new cascade and the new revocation default.
  • neotoma auth session's hardware_supported_reason is 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 software under the default enforce mode (and produces audit-trail evidence under log_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 returns jwks_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 exercises enforce, log_only, and disabled modes 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 unless NEOTOMA_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/ and tests/ are updated for the new tier values, the new attribution.decision shape, and the new failure_reason codes.
  • tests/integration/aauth_resource_metadata.test.ts continues to lock in the dereferenceable jwks_uri and empty JWKS response.
  • tests/integration/aauth_sandbox_attribution_partition.test.ts and tests/integration/aauth_sandbox_write_admission.test.ts continue 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.1 reports the additive attestation.revocation field on AttributionDecision, 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

  1. Tier semantics changed. Agents that previously rendered as hardware purely because of ES256 / EdDSA now render as software unless they present verified attestation. Tooling, dashboards, ACLs, and CI gates that branch on attribution.tier === "hardware" MUST be reviewed before upgrading. Operators that need a smoother migration window should consider min_tier=operator_attested (admits the operator allowlist + hardware) or min_tier=software.
  2. NEOTOMA_AGENT_CAPABILITIES_* removed. The env-driven per-agent capability registry and the committed default JSON file are removed. Operators MUST run neotoma 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.
  3. Revocation enforcement on by default. NEOTOMA_AAUTH_REVOCATION_MODE=enforce is the new default. Agents whose attestation keys appear on Apple's anonymous-attestation revocation endpoint, on the OCSP responder for their webauthn-packed leaf, or on the OCSP / CRL chain for their tpm2 AIK demote from hardware (or operator_attested) to software with failure_reason: "revoked". Operators that need a soak window should set NEOTOMA_AAUTH_REVOCATION_MODE=log_only ahead of upgrading.
  4. attribution.decision shape grew. New required fields under attestation and operator_allowlist_source; new optional attestation.revocation sub-object. Field additions are backwards compatible, but consumers that asserted exact-shape equality on the decision object will need to update.
  5. NEOTOMA_MIN_ATTRIBUTION_TIER=hardware is stricter. Pre-attestation agents that previously satisfied this gate are rejected with ATTRIBUTION_REQUIRED until they upgrade.

Rollback

  • Sandbox: redeploy the previous sandbox image. No migrations are required.
  • npm: v0.7.1 remains available; consumers can pin with npm install [email protected]. Rolling back returns the env-driven capability registry, the algorithm-based hardware promotion, and removes operator_attested, agent_grant, and the entire attestation framework. Agents minted via neotoma auth keygen --hardware continue 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=disabled suppresses 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.1v0.8.0)

  • 8a3b724 chore(release): v0.8.0
  • 7388a58 release: v0.8.0 — hardware attestation, agent grants, AAuth as first-class auth

Full compare: v0.7.1...v0.8.0

v0.7.1 Breaking risk
Notable features
  • 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.0v0.7.1view 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, /mcp admission, aauthVerify middleware semantics, or sandboxDestructiveGuard.

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.json advertising the issuer, supported algorithms (ES256, EdDSA), supported token typ (aa-agent+jwt), signature window (60), and an explicit jwks_uri: null with a jwks_uri_reason documenting that Neotoma is verifier-only and agents convey JWKs per-request via the Signature-Key header.
  • 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 shared SANDBOX_PUBLIC_USER_ID. Same key on two requests resolves to the same user_id; different keys resolve to different user_ids. Unsigned requests keep the existing public-user fallback unchanged. Read paths inherit the partition automatically because every read scopes by req.authenticatedUserId.
  • Sandbox gains a public AAuth admission demo. A new sandbox-only route, POST /sandbox/aauth-only/store, registered only when NEOTOMA_SANDBOX_MODE=1, explicitly rejects unsigned requests with 401 AAUTH_REQUIRED and otherwise delegates to the existing /store handler. 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 the dist/server.js entry point) now serves GET /.well-known/aauth-resource.json with 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 applied aauthVerify middleware.
  • The internal /store POST handler is now exposed as a named function (handleStorePost) inside src/actions.ts. This is a pure code-organization refactor with no behavioral change for POST /store; existing /store integration tests pass unchanged.
  • src/services/local_auth.ts adds ensureSandboxAauthUser(thumbprint) and a small hashStringToUserId helper (the existing hashEmailToUserId now delegates to it). The sandbox AAuth users use aauth-<short-thumbprint>@sandbox.neotoma.local as 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.ts now reads req.aauth?.verified and req.aauth?.thumbprint (populated by the existing global aauthVerify middleware) 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/store route is registered inside the existing if (isSandboxMode()) block, so it physically does not exist in non-sandbox builds. It uses the same writeRateLimit and request shape as POST /store.

Shipped artifacts

  • The npm package picks up the new metadata route handler, the ensureSandboxAauthUser / hashStringToUserId helpers in dist/services/local_auth.js, and the handleStorePost extraction in dist/actions.js.
  • openapi.yaml is not materially tightened in this release; the openapi:bc-diff preflight reports no breaking changes versus v0.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)."
    }
    

    issuer is derived from canonicalAauthAuthority(): it trusts an explicit NEOTOMA_AAUTH_AUTHORITY configuration 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 to POST /store, but admission is gated by a verified AAuth signature. Unsigned requests get 401 with error_code: "AAUTH_REQUIRED". Registered only when NEOTOMA_SANDBOX_MODE=1; returns 404 (route not registered) in non-sandbox deployments.

  • No changes to POST /store, POST /entities/query, GET /entities/:id, GET /stats, OAuth flows, Bearer flows, /mcp admission, or any other existing route. Internal handler organization changes (extraction of handleStorePost) are not observable through any HTTP contract.

Behavior changes

  • On sandbox.neotoma.io (and any other deployment running with NEOTOMA_SANDBOX_MODE=1), AAuth-signed requests now land on a deterministic per-thumbprint user_id instead of the shared SANDBOX_PUBLIC_USER_ID. As a direct consequence, two AAuth-signed agents see disjoint slices of the entity graph through /stats, POST /entities/query, and GET /entities/:id. Unsigned sandbox requests are unchanged: they continue to attribute to SANDBOX_PUBLIC_USER_ID.
  • A new log line, auth_method=sandbox_aauth user_id=<...> thumbprint=<...>, appears for AAuth-attributed sandbox requests; the existing auth_method=sandbox_public log 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.json endpoint.

Tests and validation

  • tests/integration/aauth_resource_metadata.test.ts locks in the contract of the new metadata endpoint: 200 with application/json, client_name === "Neotoma", signature_window === 60, supported_algs includes ES256 and EdDSA, supported_typ includes aa-agent+jwt, jwks_uri === null, and issuer is a non-empty string (host or fully-qualified URL).
  • tests/integration/aauth_sandbox_attribution_partition.test.ts mirrors the production sandbox bypass branch in a minimal Express app and exercises it via real HTTP with @hellocoop/httpsig mocked at the module level. It locks in: (i) unsigned → SANDBOX_PUBLIC_USER_ID, (ii) signed → a deterministic id distinct from SANDBOX_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 cover ensureSandboxAauthUser directly, including UUID shape, determinism per thumbprint, distinct ids per thumbprint, and rejection of empty / non-string inputs.
  • tests/integration/aauth_sandbox_write_admission.test.ts validates the γ-write contract end-to-end: unsigned POST /sandbox/aauth-only/store401 AAUTH_REQUIRED, AAuth-signed POST200 with the response user_id matching ensureSandboxAauthUser(thumbprint).id, requests with a failed AAuth verification → 401, and the route is absent (404) when not registered (the non-sandbox case). The existing tests/integration/store_*.test.ts coverage continues to validate the underlying handleStorePost behavior unchanged.
  • npm run -s openapi:bc-diff -- --base v0.7.0 reports no breaking changes.

Internal changes

  • src/actions.ts extracts the /store POST handler from an anonymous closure into a named async function handleStorePost(req, res) so both POST /store and the sandbox-only POST /sandbox/aauth-only/store route can bind it. This is a pure refactor.
  • src/services/local_auth.ts factors the existing hashEmailToUserId into a shared hashStringToUserId(input) helper, used by both hashEmailToUserId and the new ensureSandboxAauthUser. Behavior of hashEmailToUserId is unchanged byte-for-byte.

Fixes

  • AAuth client libraries can now auto-configure against any Neotoma instance from a single GET /.well-known/aauth-resource.json fetch instead of failing the discovery probe.
  • Sandbox AAuth-signed writes are no longer indistinguishable from anonymous sandbox writes: the entity graph, the Inspector, /stats, and POST /entities/query now all show the signing agent's identity instead of collapsing it to SANDBOX_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-derived local_auth_users rows written by α are functionally inert (cannot be used to log in) and can be ignored, or pruned offline if desired.
  • npm: v0.7.0 remains intact on the registry; consumers can pin or downgrade with npm install [email protected].

Commits (v0.7.0v0.7.1)

  • 5a27254 AAuth v0.7.1: metadata + sandbox attribution (α) + sandbox-only AAuth-required write (γ-write)
  • 98ad7f9 Add Tier 2 real-LLM eval harness with passing OpenAI cassettes

Full compare: v0.7.0...v0.7.1

v0.7.0 Breaking risk
Notable features
  • 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.io now 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 to agent.neotoma.io only 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-engineering pages, 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 as GET /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 by src/services/root_landing/, instead of dropping browsers onto a generic 404. The same surface returns HTML, Markdown, or JSON depending on Accept.
  • 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, and scripts/schedule_sandbox_reset.sh add an operator workflow for wiping and reseeding the public demo deterministically from tests/fixtures/sandbox/manifest.json.
  • tsconfig.scripts.json is introduced so the sandbox/reset/cron scripts compile into dist/scripts/* as part of the server build instead of staying tsx-only.

Runtime / data layer

  • src/actions.ts adds 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.ts and src/services/sandbox/local_store.ts mirror 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.ts seeds sandbox_abuse_report so 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.yaml is not materially tightened in this release, and the openapi:bc-diff preflight reports no breaking changes versus v0.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.txt is 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/terms
    • POST /sandbox/report
    • GET /sandbox/report/status
  • New local admin proxy routes for the feedback pipeline:
    • GET /admin/feedback/preflight
    • GET /admin/feedback/pending
    • GET /admin/feedback/by_commit/:sha
    • POST /admin/feedback/:id/status
  • The sandbox report relay on agent.neotoma.io adds Netlify-backed POST /sandbox/report/submit and GET /sandbox/report/status so 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_incremental return 403 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.0 work already committed on main: 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-hooks now includes an afterToolUse hook that records passive tool_invocation observations 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.json instead of clobbering it, and strips only Neotoma-owned hook entries when uninstalling.
  • packages/cursor-hooks/hooks.template.json and 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 resolved hardware or software AAuth tier before it will forward anything to agent.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.ts so 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, and CryptoEngineeringLandingPage, 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/terms JSON do not drift.
  • frontend/src/components/CliDemoInteractive.tsx expands the interactive product demo to cover chat, CLI, agentic, API, and Inspector views, using the new InspectorPreviewIllustration asset and refreshed scenario copy.
  • frontend/src/components/DetailPage.tsx adds 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.md now documents the hosted root landing page, GitHub Pages setup, and the Fly/Netlify deployment posture for hosted surfaces.
  • docs/subsystems/sandbox_deployment.md documents the sandbox architecture, seed-data policy, weekly reset workflow, abuse reporting pipeline, and moderation runbook.
  • fly.sandbox.toml and .github/workflows/sandbox-weekly-reset.yml add a repeatable deployment/reset story for the public demo.
  • services/agent-site/netlify.toml wires 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, and src/services/local_auth.ts are 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.0 remove 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.0 reports 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, and tests/unit/sandbox_reset.test.ts.
  • The release scope also includes fixture coverage for sandbox reseeding under tests/fixtures/sandbox/.

Breaking changes

No breaking changes.

v0.6.0 Breaking risk
Notable features
  • 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.1v0.6.0view 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_source tagging, reply-cited provenance edges (Step 5b.1), an Ambiguous (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, and neotoma 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 via neotoma snapshots export|diff|parsers|check|request.
  • Multi-agent conversations as first-class data. conversation_message with sender_kind (user / assistant / agent / system / tool) plus stable sender_agent_id / recipient_agent_id give real agent-to-agent routing and reporting; thread_kind (human_agent / agent_agent / multi_party) describes participant topology; stricter turn_key / conversation_id guidance keeps unrelated threads from silently merging.
  • A structured agent feedback loop. Agents can submit_feedback, poll for resolution with get_feedback_status (respecting next_check_suggested_at), receive install/upgrade guidance, and verify fixes; the new agent.neotoma.io Netlify 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/split and the split_entity MCP tool rebind a subset of observations to a new entity by time range, source, or field match, producing an entity_splits audit record instead of an irreversible delete/re-insert.

What changed for npm package users

CLI (neotoma)

  • neotoma auth session — calls GET /session and prints the resolved trust tier, identity, and eligible_for_trusted_writes, merging any local cli_signer state.
  • neotoma auth keygen — writes a local AAuth keypair under ~/.neotoma/aauth/; flags: --alg, --sub, --iss, --force.
  • neotoma auth sign-example — prints a signed curl example targeting /session so operators can sanity-check signing end-to-end.
  • neotoma api start --env prod on source checkouts now defaults to the built production runner (dist/…) instead of the dev:prod watcher. Pass --watch to restore the previous tsx-watcher behavior under NEOTOMA_ENV=production.
  • --observation-source <kind> is threaded through store-oriented flows so operators/agents can label writes as sensor, workflow_state, llm_summary, human, or import instead 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 via POST /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 the product_feedback entity 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 unknownFieldsGuard that rejects undeclared top-level keys on closed schemas before route handlers run.
  • Helmet CSP tightens by default (connectSrc: ['self']); operators can allow additional hosts via NEOTOMA_CSP_CONNECT_SRC (comma-separated list).
  • Per-user/IP write rate limit lands via writeRateLimit with a default cap of 120 writes/minute, tunable through NEOTOMA_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=1 causes 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 Host header, so tunneled requests no longer masquerade as local.
  • The observation reducer tie-breaks on observation_source after source_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.yaml grows ~900 lines for the new session, agents, entity-split, attribution, provenance, feedback, and validation surfaces; src/shared/openapi_types.ts is regenerated to match.
  • Updated schema snapshots land under docs/subsystems/schema_snapshots/ for conversation (v1.0–v1.2), agent_message (v1.0–v1.1, retained as alias), and new conversation_message (v1.0–v1.2).
  • The npm package picks up the CLI/runtime changes plus the updated docs and snapshots via the existing files list (dist, openapi.yaml, openclaw.plugin.json, skills, LICENSE, README.md). The files list itself is unchanged.

API surface & contracts

New HTTP routes

  • GET /session — resolved attribution tier, client identity, anonymous-write policy, and eligible_for_trusted_writes, plus a diagnostic attribution.decision block 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 an entity_splits audit row.
  • GET /sources/{id}/relationships — enumerate relationships associated with a source without ad-hoc queries.
  • POST /health_check_snapshots — fleet snapshot export endpoint consumed by neotoma snapshots check|request.

Expanded existing routes

  • GET /sources/{id} now includes a provenance block describing where the source came from.
  • POST /create_relationship responses and GET /relationships/{id} include an agent_attribution block.
  • POST /entities/query accepts identity_basis for finer-grained resolution/query semantics.
  • POST /relationships/snapshot accepts an optional user_id for scoped snapshots.
  • Observation, TimelineEvent, Interpretation, and Source response shapes carry richer provenance fields so reads surface the same attribution metadata writes produce.
  • StoreResolutionIssue.hint and related error payloads are expanded with migration-oriented guidance instead of opaque resolution failures.

New MCP tools

  • get_session_identity — MCP equivalent of GET /session; use in initialize or before enabling writes.
  • split_entity — MCP equivalent of POST /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 newer neotoma npm 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 prod on source checkouts runs the built artifact by default. The old dev:prod watcher path is no longer the default production route; pass --watch when you explicitly want watcher behavior.
  • Unknown top-level request fields on closed write/auth endpoints fail fast. The unknownFieldsGuard runs 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 session instead 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 set NEOTOMA_CSP_CONNECT_SRC.
  • Write traffic is rate-limited by default. Bursty writers see HTTP 429 after 120 writes/minute per user or IP; tune with NEOTOMA_WRITE_RATE_LIMIT_PER_MIN.
  • Loopback-only routes no longer trust the Host header. 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 an Ambiguous (N) section in chat.
  • Chat hooks emit conversation_message with sender_kind. Cursor, Claude Code, Codex, OpenCode, and Claude Agent SDK hook packages all produce the new canonical shape; agent_message continues to be accepted as an alias at write time.
  • Reducer outputs may shift. When observation_source is set on a new write, it tie-breaks against unclassified legacy observations via the reducer's source_priorityobservation_source ordering; 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_source usage — 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_message canonicalization — new writes use conversation_message + sender_kind; agent_message remains an accepted alias for pre-v0.6 clients.
  • A2A fields — agent-to-agent traffic is expected to set sender_kind: "agent" with sender_agent_id / recipient_agent_id; conversation.thread_kind categorizes the thread topology.
  • Reply-cited provenance edges (Step 5b.1) — the closing assistant store now includes REFERS_TO edges 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 structured HEURISTIC_MERGE warnings from store responses in chat alongside Created/Updated/Retrieved.
  • [ATTRIBUTION & AGENT IDENTITY] block — codifies AAuth preflight via get_session_identity / GET /session / neotoma auth session, forbidden clientInfo values, trust-tier badging, and impersonation policy.
  • [FEEDBACK REPORTING] block — when to submit feedback, PII redaction expectations, persisting a product_feedback record with access_token, polling via get_feedback_status, handling upgrade_guidance, and responding to verification_request.
  • npm_check_update hint — agents may call it at session start and prompt the user to upgrade when a newer neotoma client 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-hooksbefore_submit_prompt.ts and stop.ts emit conversation_message + sender_kind and propagate AAuth-aware session metadata.
  • packages/codex-hookssession_end.py propagates session/agent metadata on stop.
  • packages/claude-code-pluginstop.py and user_prompt_submit.py align 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.ts exposes ChatTurnSenderKind, the new sender_kind, A2A id fields, and canonical conversation_message typing; diagnose.ts and turn_report.ts align with the new attribution/diagnostic surface.

Agent feedback pipeline (end-to-end)

  • MCP entry pointssubmit_feedback for agents to report friction; get_feedback_status for polling with backoff respecting next_check_suggested_at.
  • Transport selectionNEOTOMA_FEEDBACK_TRANSPORT=local|http, AGENT_SITE_BASE_URL, AGENT_SITE_BEARER; kill-switch NEOTOMA_FEEDBACK_AUTO_SUBMIT=0 disables proactive submission.
  • Local storesrc/services/feedback/local_store.ts persists 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 a redaction_preview so agents can audit what was transformed.
  • Upgrade guidance — resolved items can carry upgrade_guidance (install_commands, verification_steps) and verification_request (with verify_by); feedback_upgrade_guidance_map.json catalogs 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 scheduled push_webhook_worker. Optionally forwards each item into Neotoma via tunnel + Cloudflare Access + AAuth (see docs/subsystems/feedback_neotoma_forwarder.md).
  • Cron ingestionscripts/cron/ingest_agent_incidents.ts classifies queued feedback, applies the upgrade-guidance map, and updates status; scripts/cron/com.neotoma.feedback-ingest.plist.template provides a launchd template.
  • Backfill + seedingscripts/feedback_mirror_backfill.ts replays historical submissions; scripts/seed_product_feedback_schema.ts (via npm run feedback:seed-schema) provisions the product_feedback entity schema in a Neotoma instance.
  • Capability registryconfig/agent_capabilities.default.json pins [email protected] to neotoma_feedback operations 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-src allow-list via NEOTOMA_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; expanded docs/subsystems/auth.md, errors.md, sources.md, entity_merge.md; docs/infrastructure/deployment.md; .env.example grows 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 plus replay.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, and components.schemas.StoreStructuredRequest now 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 HTTP 400, error_code: ERR_UNKNOWN_FIELD, and a structured details payload containing allowed_fields, unknown_fields, and json_paths. Migration: send only declared top-level keys (entities, relationships, source_priority, observation_source, idempotency_key, file-related fields, commit, strict, user_id as applicable) and move entity-specific data inside the individual entities[] objects.
  • POST /store/unstructured and components.schemas.StoreUnstructuredRequest now reject undeclared top-level fields. Before: callers could include extra wrapper keys alongside the upload payload. After: HTTP 400 with error_code: ERR_UNKNOWN_FIELD and a structured details payload. Migration: limit the body to file_content, mime_type, idempotency_key, original_filename, user_id.
  • POST /relationships/snapshot and components.schemas.GetRelationshipSnapshotRequest now reject undeclared top-level fields. Before: extra keys could slip through until the route-level validator ran. After: rejected earlier with HTTP 400 / ERR_UNKNOWN_FIELD. Migration: send only relationship_type, source_entity_id, target_entity_id, user_id (the last is newly optional).
  • POST /mcp/oauth/initiate and components.schemas.OAuthInitiateRequest now reject undeclared top-level fields. Before: callers could include extra auth-initiation metadata at the request root. After: HTTP 400 / ERR_UNKNOWN_FIELD. Migration: restrict requests to connection_id, client_name, redirect_uri.
  • POST /correct now rejects undeclared top-level fields. Before: extra root-level keys were not contractually forbidden at the HTTP boundary. After: HTTP 400 / ERR_UNKNOWN_FIELD. Migration: limit the body to entity_id, entity_type, field, value, idempotency_key, user_id.
  • neotoma api start --env prod on source checkouts now runs the built runner by default. Contributors or automation that relied on the old dev:prod watcher must switch to neotoma api start --env prod --watch. The dev:prod npm script alias itself is unchanged.
  • Default Helmet CSP restricts connect-src to 'self'. Deployments that served browser UI from the API and relied on permissive outbound connections must opt in via NEOTOMA_CSP_CONNECT_SRC.
  • Default write rate limit of 120 writes/minute per user/IP. Bursty writers receive HTTP 429; tune via NEOTOMA_WRITE_RATE_LIMIT_PER_MIN or batch via store_structured.
  • Loopback classification changed. Requests routed through tunnels/proxies are no longer treated as local even when they carry a localhost Host header; deployments that relied on this behavior for lightweight dev-auth must switch to AAuth or an explicit allow-list.

Commits (v0.5.1v0.6.0)

  • dd5ed95 Bump version to v0.6.0
  • 6a58115 Pre-release: include changes for v0.6.0

Full compare: v0.5.1...v0.6.0

v0.5.1 Breaking risk
Notable features
  • 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.0v0.5.1view 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-id flags on neotoma entities get and neotoma stats (the two read verbs that were missing them); existing read verbs continue to honor --user-id.
  • New NEOTOMA_USER_ID environment variable with flag > env > default precedence, joining NEOTOMA_API_ONLY and NEOTOMA_OFFLINE in 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 to LOCAL_DEV_USER_ID.
  • neotoma store and neotoma store-structured now print a stderr warning in commit mode when the response reports entities_created=0 and 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 (flatten attributes, check user scope, check registered schema).
  • neotoma ingest grows two new flags: --source-upload forces byte upload regardless of transport; --source-content <inline> skips the filesystem entirely and base64-encodes the provided string. By default, ingest now auto-detects non-localhost base URLs (tunnel / remote production) and switches from file_path to file_content so tunneled client/server topologies no longer fail with ENOENT when the server can't read the client's filesystem. Localhost / offline callers keep file_path to 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 prod on 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 json to 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 explicit replayed: boolean field. true on the existing-source idempotency-replay branch (same (user_id, idempotency_key) as a prior commit); false on 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_FAILED issue objects gain an optional hint: string field. The server populates it with structured upgrade guidance when CanonicalNameUnresolvedError.seen_fields is exactly {"attributes"} or {"entity_type", "attributes"} — i.e. a caller is still sending the pre-0.5.0 attributes: { … } 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.yaml declares: user_id as an optional query parameter on GET /entities/{id} and GET /stats; replayed: boolean on StoreStructuredResponse; new StoreResolutionIssue (with hint) and StoreResolutionErrorEnvelope schemas; StoreResolutionErrorEnvelope wired to the 400 response for POST /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 the GET /recent_conversations operation. src/shared/openapi_types.ts regenerated 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=…. The user_id param is optional and is still validated through the existing getAuthenticatedUserId gate; it does not widen the existing dev-override surface (only LOCAL_DEV_USER_ID auth contexts may pass a different user_id; real Bearer-authenticated callers still get 403 on mismatched ids).
  • New error field: StoreResolutionIssue.hint?: string (optional). Emitted today for the attributes-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, richer GET /entities/{id} response metadata (entity_type_label, primary_fields, created_at), and expanded GET /entities/{id}/relationships?expand_entities=true response fields for caller-friendly source/target labels. contract_mappings.ts now maps getRecentConversations as an HTTP-only infra surface.

Behavior changes

  • /store idempotency replay is now explicit. Clients that inspected entities_created_count: 0 as a proxy for replay-vs-failure should switch to the new replayed field. The CLI's new commit-mode stderr guard does exactly this: it fires only when entities_created=0 AND replayed !== true AND no entities were matched/updated.
  • attributes-nested payloads surface upgrade guidance. Callers still sending {"entity_type": "…", "attributes": { … }} receive a structured hint in every ERR_STORE_RESOLUTION_FAILED issue 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 ingest over remote transports changes its request shape automatically. Non-localhost / non-offline base URLs send file_content (base64) + mime_type + original_filename instead of file_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 prod is no longer silent on source checkouts. It still routes through dev:prod (tsx watcher) for contributors who rely on hot-reload in NEOTOMA_ENV=production, but now prints a single stderr line directing headless-deployment operators at the supervised systemd recipe in install.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_activity items 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_conversations returns 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.md adds:
    • NEOTOMA_USER_ID row in the Runtime overrides table with precedence and empty-value rejection.
    • Store section entries for the new replayed flag 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.md gains 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 check continues to pass.
  • docs/developer/mcp/instructions.md keeps the v0.5.1 CLI/MCP parity bullets and also adds human-readable naming guidance for chat artifacts (agent_message.canonical_name and conversation.title) so stored chat rows present better labels downstream.
  • install.md adds a new Production deployment (headless / systemd) subsection with a tested neotoma.service unit file, env var list, the ProtectSystem=no / PrivateTmp=no caveat for /usr/lib/node_modules/neotoma resolution, and a forward reference to docs/operations/runbook.md.
  • docs/operations/runbook.md cross-links back to the new install-md section from its production deployment block.
  • docs/subsystems/auth.md documents 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.md documents the new hint field on ERR_STORE_RESOLUTION_FAILED issues.

Internal changes

  • src/actions.ts: storeStructuredForApi sets replayed: true on the idempotency-replay branch and replayed: false on every fresh-commit return path; the CanonicalNameUnresolvedError → HTTP mapping computes an attributes-specific hint via a new buildAttributesHint helper and preserves the optional hint field through the error envelope.
  • src/cli/index.ts: new resolveEffectiveUserId() helper threads --user-id / NEOTOMA_USER_ID through every read verb; new isLocalhostBaseUrl() helper handles IPv4, IPv6, and hostname-equivalence cases; new --source-upload / --source-content flags and auto-upload branch on ingest; commit-mode stderr guard on store / store-structured; stderr advisory on api start --env prod (background branch is guarded on outputMode !== "json").
  • Inspector/read-model services: src/services/recent_conversations.ts adds a SQLite-backed recent-conversations aggregator with nested message/entity expansion; src/services/recent_record_activity.ts exposes richer typed fields and a server-computed group_key; src/services/entity_queries.ts adds schema-derived entity_type_label and primary_fields; src/shared/contract_mappings.ts maps the HTTP-only getRecentConversations operation.

Fixes

  • store --file vs store --entities parity. With NEOTOMA_USER_ID fixed on both calls, both paths create equivalent entities with the same entities_created_count, identical entity ids, and the same replayed flag 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-id now actually scopes the write. The CLI now forwards user_id to /create_relationship, and the API resolves it through getAuthenticatedUserId() instead of hard-coding the single-user UUID. This restores parity with relationships list/delete/restore and fixes cross-layer tenant-scoped relationship flows.
  • ingest over tunneled client/server. The CLI no longer sends a client-side file_path the server cannot read; remote transports carry the bytes in the request body.
  • Untracked src/shared/openapi_types.ts drift. Regenerated alongside every openapi.yaml change; the contract-parity tests in tests/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.tsNEOTOMA_USER_ID env var, per-call --user-id flag override, and flag wiring across every read verb.
    • tests/cli/cli_store_file_vs_entities_parity.test.ts--file vs --entities produce equivalent results for the same payload; second call with the same --idempotency-key returns replayed: true on both paths; commit-mode stderr guard is wired on store and store-structured.
    • tests/integration/store_resolution_attributes_hint.test.tsERR_STORE_RESOLUTION_FAILED includes the hint when fields are nested under attributes; absent for unrelated unresolved-name cases.
    • tests/cli/cli_ingest_remote_upload.test.tsisLocalhostBaseUrl IPv4/IPv6/hostname coverage; auto-upload on non-localhost base URLs; --source-upload forces 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 on outputMode !== "json".
  • Existing inspector/contract surfaces also ride the release: openapi.yaml and src/shared/openapi_types.ts now cover GET /recent_conversations plus 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.0v0.5.1)

  • a2d569b Bump version to v0.5.1
  • 3f0d9d9 Pre-release: include v0.5.1 changes

Full compare: v0.5.0...v0.5.1

v0.5.0 Breaking risk
Breaking changes
  • /store payloads: entity fields must be at top level, not nested under 'attributes'
Notable features
  • 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 /store payloads (v0.5.0): entity fields must be at the top level of each entity object. Callers that still nest fields under attributes (e.g. { entity_type, attributes: { title, canonical_name, … } }) will see ERR_STORE_RESOLUTION_FAILED with ERR_CANONICAL_NAME_UNRESOLVED and seen_fields: ["attributes"].

Fix: flatten your payload to { entity_type, title, canonical_name, … }. Starting in v0.5.1, the server response includes a structured hint on 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.1 release notes for the full follow-up (attributes hint, replayed: true flag, NEOTOMA_USER_ID env-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.5v0.5.0view 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 with matched_fields and score. Confirm with the user, then hand off to neotoma request --operation mergeEntities. Never auto-merges.
  • neotoma stats now supports --by identity-basis to 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 list and neotoma observations list gain --since <timestamp> filters (maps to updated_since / created_since on the query).
  • neotoma doctor and neotoma mirror get additional self-check and diagnostic paths; resolveBaseUrl records transport meta so transport choice is auditable across --api-only, --offline, and env flags.
  • neotoma cli-instructions check ships 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_schema now requires schemas to declare either canonical_name_fields (ordered precedence list of single-field or composite rules) or an explicit identity_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_fields now 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 /store response, the MCP tool response, and a new observations_by_identity_basis aggregation on /stats.
  • New post-hoc fuzzy duplicate detector. Per-schema config via duplicate_detection_fields (snapshot fields compared beyond canonical_name) and duplicate_detection_threshold (similarity 0..1, default 0.85). Read-only; hands off to /entities/merge once 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, plus task, note, project, location) use real canonical_name_fields; the long tail carries identity_opt_out: "heuristic_canonical_name" so the gap is visible rather than silent.

Shipped artifacts

  • openapi.yaml and regenerated src/shared/openapi_types.ts include the new GET /entities/duplicates endpoint, extended Stats (observations_by_identity_basis), and extended StoreStructuredResponse (identity_basis). New MCP tool list_potential_duplicates is wired through tool definitions, server dispatch, and contract_mappings.
  • New JavaScript client helpers in packages/client: diagnose.ts, helpers.ts, turn_report.ts (plus exports from index.ts), aimed at turn-shaped agent workflows. Client README and package.json updated 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 ranked candidates[] with entity_a, entity_b, score, matched_fields, entity_type.
  • Extended response fields:
    • StoreStructuredResponse now includes a structured identity_basis per resolved entity.
    • Stats now includes observations_by_identity_basis: Record<IdentityBasis, number>.
  • Query schema additions: EntitiesQueryRequestSchema and ObservationsQueryRequestSchema accept updated_since / created_since.
  • Schema definition vocabulary (additive): canonical_name_fields rule-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_duplicates must confirm candidate pairs with the user (or repair plan) before calling merge_entities. The detector is strictly post-hoc and never runs during write-time identity resolution; write-time identity stays deterministic via entity_type + canonical_name (hash unchanged).
  • /register_schema payloads that omit both canonical_name_fields and identity_opt_out still succeed but are logged (server-side warning) and appear under the "heuristic fallback" bucket in neotoma stats --by identity-basis. Operators should migrate these schemas to declared identity over time.
  • identity_basis appears in /store responses, 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_fields form lets a schema express "prefer email; 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 by neotoma cli-instructions check into the user-level ~/.cursor/rules, ~/.claude/rules, and ~/.codex targets.
  • New MCP tool description for list_potential_duplicates in docs/developer/mcp/tool_descriptions.yaml.
  • docs/subsystems/entity_merge.md Section 7 rewritten to document R5 duplicate detection (schema-driven config, CLI/MCP surfaces, read-only constraint).
  • docs/developer/cli_reference.md and docs/subsystems/markdown_mirror.md refreshed.
  • install.md expanded with additional onboarding guidance (+53 lines).
  • New integrations doc: docs/integrations/smithery_external_url.md.

Internal changes

  • Resolver rewrite: src/services/entity_resolution.ts now walks ordered canonical_name_fields rules and attaches a structured identity_basis to every ResolverTrace. Canonical-name derivation exposes a traced form (deriveCanonicalNameFromFieldsWithTrace).
  • Schema registry validation in src/services/schema_registry.ts enforces R2; a new logIdentityOptOutsAtStartup method enumerates opt-outs at boot.
  • New service src/services/duplicate_detection.ts with stringSimilarity (normalized Levenshtein, reusing src/normalize.ts's levenshtein) and findDuplicateCandidates.
  • MCP server (src/server.ts) gains a listPotentialDuplicates dispatch path. Tool definitions (src/tool_definitions.ts) add the schema; contract mappings (src/shared/contract_mappings.ts) tie the MCP tool to listPotentialDuplicates OpenAPI operationId and to the new CLI verb.
  • src/services/snapshot_computation.ts, src/services/observation_storage.ts, src/services/entity_queries.ts, and src/shared/action_handlers/entity_identifier_handler.ts updated to carry identity_basis end-to-end.
  • Agent-shaped helpers: src/services/recent_record_activity.ts feeds the CLI recent/ingest surfaces; src/mcp_server_card.ts exposes a structured server card.

Fixes

  • Site: fix(site): clarify install/evaluate prompts and install page flow and fix(site): streamline permissions preflight for install and evaluate (shipped commits on main since 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.ts and src/repositories/sqlite/sqlite_client.ts.
  • Schema registration back-compat default for identity_opt_out prevents 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.ts asserts observations_by_identity_basis; tests/services/entity_resolution.test.ts covers ordered-precedence and identity_basis threading; tests/services/schema_registry_incremental.test.ts and numerous tests/integration/mcp_*.test.ts fixtures updated for R2's mandatory identity declaration.
  • OpenAPI types regenerated via npm run openapi:generate and tests/contract/openapi_schema.test.ts covers the new MCP-tool-to-operationId mapping.

Breaking changes

  • Schema registration (softened): Schemas MUST declare canonical_name_fields or identity_opt_out. For existing callers, the /register_schema HTTP/CLI handler injects identity_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-basis and 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.5v0.5.0)

  • a59834a Bump version to v0.5.0
  • bdf474c Pre-release: include changes for v0.5.0
  • deaab88 fix(site): clarify install/evaluate prompts and install page flow
  • 444a076 fix(site): streamline permissions preflight for install and evaluate

Full compare: v0.4.5...v0.5.0

v0.4.5 Breaking risk
Notable features
  • 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.4v0.4.5view 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 doctor as 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.ts so 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.md exports 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_snapshot now documents a format selector (markdown default for MCP, json for 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 with neotoma 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.md export 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.4v0.4.5)

  • e1946fb Version bump to v0.4.5
  • b18e5e3 Pre-release: include pending changes for v0.4.5

Full compare: v0.4.4...v0.4.5

v0.4.3 Breaking risk
Breaking changes
  • Bundled operational frontend screens removed; marketing-first experience only
Notable features
  • 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.2v0.4.3view 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, and src/tool_definitions.ts, plus contract coverage in tests/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.ts is 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.ts means previously bundled HTTP or app-facing behavior should be treated as changed unless confirmed otherwise in final validation.

Behavior changes

  • The committed main range 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 /release previews 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.ts and frontend/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.ts is heavily reduced; any consumers depending on previous bundled server behavior should validate routes and integrations before upgrading.
  • Ship constraints: docs/private is 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.2v0.4.3)

  • a34156d docs(release): add v0.4.3 GitHub release supplement
  • 9cd526f chore(release): bump version to v0.4.3
  • 3fd62eb refactor(site): narrow public UI and add OpenClaw packaging
  • 3b41faf feat(site): responsive evaluate prompt layout and mobile copy tests
  • 8f9b587 feat(site): marketing site refresh, docs, and walkthrough route SEO
  • 248b89d Merge dev into main for v0.4.2 release
  • d28bb9e Merge dev into main (marketing site updates)

Full compare: v0.4.2...v0.4.3

v0.4.2 Breaking risk

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.1v0.4.2view 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/server through package exports instead of failing on a missing server/index.js path.
  • Updated tsconfig.json to module: NodeNext and moduleResolution: NodeNext so the runtime import and type resolution agree.
  • Regenerated the packaged dist/ output for the 0.4.2 publish target.

Site and docs

  • Extracted FAQ content into frontend/src/site/faq_items.ts, simplifying FaqPage.tsx and 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.md and docs/developer/mcp/instructions.md.
  • Included the current hooks-planning notes under .cursor/plans/ in the released scope.

Fixes

  • Fixed ERR_MODULE_NOT_FOUND for 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, and npm 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.1v0.4.2)

  • 68cb675 Release v0.4.2
  • 9e2e83b fix(site): hero spacing, install CTA classes, scroll banner meet link
  • 17a4d2c docs(release): refresh v0.4.1 GitHub release notes and supplement
  • 5258b9f fix(site): keep record-types headline tail on one line

Full compare: v0.4.1...v0.4.2

v0.4.1 Breaking risk
Notable features
  • 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.0v0.4.1view 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): 5258b9f3fix(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 as recover:db and recover:db:prod. The flow runs PRAGMA 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 /release workflow so GitHub/npm releases are prepared from the real shipped scope, including committed dev work, explicit uncommitted-change previews, and clearer compare-range handling.
  • Continued CLI/API/runtime refinement across src/cli/index.ts, src/actions.ts, and src/server.ts, including the release-candidate stability fix that makes CLI tests use the shared test API server in NODE_ENV=test unless --offline is 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.yaml and the generated dist/ 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, and src/shared/openapi_types.ts all 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_positioning skill 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 /release while keeping /create_release as 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 writ submodule (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.ts to remove flaky per-command local transport startup during CLI test runs.

Fixes

  • Fixed the docs sidebar toggle path for /evaluate and /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.1 candidate 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, and npm 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.1 tag exists on 8081ee5; re-run npm run -s release-notes:render -- --tag v0.4.1 after any tag movement before publishing or editing the GitHub Release.

Breaking changes

  • None called out for 0.4.1.

Commits (v0.4.0v0.4.1)

  • 80203f2 Release v0.4.1: incremental deploy (marketing site)
  • 5a95524 Merge dev into main for release v0.4.1 (marketing site)
  • 9c62ea4 FU-301: Marketing site refresh, SEO, and v0.4.1 prep docs
  • 56d4b50 chore: add writ submodule (WRIT write-integrity benchmark)
  • 2665395 fix(claude): emit skills as .claude/skills//SKILL.md
  • 5e816a2 Sync .cursor/skills into Claude skills when not in foundation
  • 8034a9b Emit all foundation commands as Claude Code skills
  • e91cacd chore(release): prepare main-repo v0.4.1 candidate
  • e3b99e5 Dev: CLI/API contracts, site UI, docs, cursor rules, inspector submodule
  • 0da9e28 docs(icp): refresh primary ICP, dev release targeting, general release criteria; anonymize evaluator PII in public docs; add private field_evidence submodule ref
  • e9ad210 fix(site): allow docs sidebar toggle on /evaluate and /install
  • 513e2ba build(site): refresh prerendered export for v0.4.0
  • 48d6396 docs(release): refresh v0.4.0 supplement for final site fixes
  • 897a22c fix(site): improve dark-surface copy contrast
  • f03869a fix(site): align intro section edge indicators
  • af63f54 chore: remove repo-root clutter (tracked branch-ports state, npm pack artifact)
  • aee67c2 docs: update foundation submodule for release guidance
  • 6ce245f refine evaluation-first site flow and public release notes
  • f91f41b docs(release): prepare v0.4.0 notes and versioning
  • c3778e4 Update marketing site navigation, scroll UX, analytics, and subpages
  • ddc25a1 fix: track DatabaseMemoryPage for Vite build (gitignore data* clash)
  • 4300731 Update marketing site, repo metadata, SEO, analytics, and home IA
  • 7119cac docs(site): ICP paths, marketing pages, workflows, and site export refresh
  • 5f1f004 Add site marketing pages, markdown hub, and SEO dev tooling
  • 6738fb5 chore(docs): bump docs/private submodule (Isaac CD trilogy + persona)
  • 1b29ead feat(site): healthcare, gov, customer-ops, logistics verticals; private doc submodule
  • ea333c2 refine(site): vertical landing shell UX and agent-auth page
  • a6ad85a fix(site): ship AgentAuthLandingPage and full-page segment for /agent-auth
  • 8fee422 feat(site): vertical index + landings, marketing full-page shell
  • 1485d9f ci(dev-pages): install Playwright Chromium before site prerender build
  • 9e1f86e feat(site): CRM/compliance verticals, timeline/schema, docs, scripts
  • 49edfe4 Release v0.3.11: site, docs, MCP/ChatGPT integration
  • 2f395c6 Prepare v0.3.10 patch release metadata.
  • c213566 fix seo title on basename-root detail pages
  • 7e1b865 Install Playwright Chromium in Pages deploy workflow.
  • d332c75 Add build-time prerendering for GitHub Pages SEO.
  • 4056ea9 Update install page content tweaks.
  • c242922 Update localized site loading and docs navigation refinements.
  • bcc074d Commit outstanding docs, frontend, and generated site updates.
  • 54af605 Fix docs UI icon wiring and guarantee table runtime regression.
  • 555377a Merge branch 'dev'
  • 77408ab Record local main-branch updates before merge.
  • 5f71e37 Update docs site cards, icons, and integration walkthrough content.
  • 930f283 Fix intermittent intro invisibility on dev homepage.
  • 3488aa2 Fix blank home sections on dev site by relaxing fade-in visibility gating.
  • a9237c0 Update site content, navigation, and integration walkthrough pages on dev.
  • 6e7a63f Restore today's recovered site redesign and asset work after rebase loss, including new ICP/interface artwork and expanded landing subpages.
  • ee2eb53 Update site content and isolate dev Pages deployment.
  • 73bd182 Fix dev site build by removing stale data-model route and fallback missing card images.
  • f9fb20f Replace missing site illustration assets with stable fallback image.
  • 98a9f49 Fix dev deploy lockfile mismatch and widen guarantees section.
  • 5b843cc Update site content and isolate dev Pages deployment.
  • 6a5007a Overhaul docs and site architecture for expanded multilingual navigation.
  • 401e560 Revert GitHub Pages content to v0.3.8.
  • 99421d3 Fix Playwright site coverage test startup.
  • d6f0c46 Release v0.3.9.
  • 81f1eda Release v0.3.8.
  • 2b6377d Fix CI install by removing local tarball self-dependency.
  • ab79c46 Merge branch 'release/v0.3.3'
  • b07926f Release v0.3.7.
  • 16e00b8 Apply post-hook updates to CLI init and site build artifact.
  • ba4ef5a Update CLI startup docs and environment handling.
  • 0b8b7b0 Release v0.3.6.
  • fb38a64 Merge pull request #22 from markmhendrickson/release/v0.3.3
  • 56c6c6f Adjust mobile table chrome and keep desktop table styling.
  • 2c3e0ac Merge pull request #21 from markmhendrickson/release/v0.3.3
  • 9105bb3 Prepare v0.3.5 and fix get-started demo asset.
  • a92e410 Merge pull request #20 from markmhendrickson/release/v0.3.3
  • c5444b2 Release v0.3.5.
  • 7f791c9 Release v0.3.4.
  • 9ed256b chore(frontend): normalize related post ordering
  • 9c03939 Release v0.3.3.
  • f2c42d0 Release v0.3.2.
  • 666962c docs: add tester checklist for init env fixes
  • 8def077 fix(cli): init .env creation and clearer env/config status
  • 062669e Finalize site updates and deployment readiness.
  • b3311cb Release v0.3.1.
  • 7ef1b01 Merge dev into main for release v0.3.1
  • 30234c7 Prepare v0.3.1 release inputs and deployment tooling.
  • fff53db Include workflow note and CLI wrapping improvements in release.
  • 83e602a Apply remaining CLI cleanup changes before release merge.
  • 9565b70 Finalize CLI init flow updates for release branch.
  • 489c2f5 Prepare v0.3.0 developer release with domain cutover.
  • 7f90811 Fix GitHub Pages root 404; improve CLI session resize and box width
  • 66f9d72 Ignore public/ build output; fix OAuth redirect and CLI box formatting
  • 8db5c36 Fix GitHub Pages sidebar and styles; deploy build:ui; CLI and test fixes
  • 79d26cb Deploy site from dev branch; rename env.example to .env.example; tunnel script tweaks
  • 83a9c01 Refactor auth workflows and align API contract coverage.
  • fff77fc Refactor auth flows, CLI fallback, and site SEO updates
  • a246a6f Refactor rules, docs, CLI tests; fix tests and data-dir exclusions
  • 22a7209 Add CLI-first agent parity, local entity embedding, and expanded test coverage
  • 72b72a0 Add deletion/GDPR and entity snapshot embeddings; expand CLI and tests
  • c6207a5 Add timeline_events service and migrations; add user_id to interpretations
  • c60dbc9 Update mcp/web-scraper submodule and doc table alignment
  • 56ff927 Add crypto layer and log encryption; update docs and SQLite adapter
  • 9eb3877 Create v0.3.0 reconciliation release and archive aspirational releases
  • b1e1f25 Update CLI, migrations, and docs/UI alignment
  • 3296f35 Consolidate cursor rules, expand design system docs, add snapshot monitoring
  • 4836f12 Update docs/private submodule to latest commit after resolving conflicts
  • f68ef4d Migrate generic development rules to foundation and add major implementation work
  • a979409 Refactor schema registry and entity queries with raw_fragments support
  • 4cef222 Improve test quality, fix auto-enhancement bugs, optimize database
  • 16adc1a Add parquet MCP resources specification
  • 35f3314 Fix CI: Check migration files only, not database state
  • 1ba6598 Update README and documentation, clean up frontend dependencies
  • 28fc875 Update README with canonical vocabulary and ignore error reports
  • e02e9d0 Update v0.2.0 release status and refactor codebase
  • aa8210f Reorganize documentation, update cursor rules, and add frontend components
  • 1d70f5e Execute v0.2.0: Minimal Ingestion + Correction Loop
  • cccb77c FU-110: Implement v0.2.0 sources-first ingestion architecture
  • ffd87ef FU-MIGRATION-001: Migrate cursor commands and rules to foundation system
  • b59501a Extract generic Cursor rules to foundation
  • 0a1f7cb Update agent instructions: add foundation submodule usage
  • c44c8e4 Update foundation: copyright year 2025
  • 4df364c Update foundation submodule: README with license
  • 066b6f9 Add foundation submodule with MIT License
  • bda6e62 Re-add foundation submodule with LICENSE
  • e078d48 Update foundation submodule to use GitHub remote
  • d6066e1 Complete foundation submodule setup
  • 9eb4a14 Convert foundation to git submodule
  • a711d60 Convert foundation to git submodule
  • c13e62e Add foundation: shared development processes
  • 8732d0a Fix database migration handling and improve error reporting
  • a019979 Separate dev/prod environment variables for security
  • a095922 Enforce strict dev/prod Supabase environment separation
  • 6739dc3 Reorganize documentation structure and update configuration
  • 7c0b443 docs: Update documentation and add integration candidates
  • 3886150 Remove credentials from notify_running_agents_credentials.js
  • 7f4b4bb Add security check to validation checklist
  • e9788b6 Remove credential passing via API environment field
  • 3109c14 Remove credentials from respawn_single_agent.js and add security prohibition
  • 0a56267 Remove unused loadCredentials call from respawn script
  • 2fa97e1 Remove credentials from agent instructions in respawn script
  • ccf55f6 Update task instructions to require all tests passing before completion
  • 8c106e6 Update orchestrator instructions to require all tests passing
  • 3cc555c Update setup script to automatically apply migrations via Management API
  • fae2af0 Configure Cursor Cloud Agents environment.json
  • cf79c84 Update orchestrator for Cursor Cloud Agents Secrets
  • 4b5e954 Update setup script to handle Supabase CLI authentication gracefully
  • 249bac0 Add automated setup script for agent environments
  • 5c2a957 fix: resolve blockers for cloud agent execution
  • 2a9e9b0 Align v0.2.x+ release execution with orchestrator
  • 58fa448 Align v0.x release docs and workflow
  • 069bacd Standardize string literals to double quotes
  • 228b320 Refactor release documentation structure and fix syntax errors
  • 415dd5a Fix doc inconsistencies: align with v0.2.0 minimal scope
  • 54c2b10 Streamline release spacing: minimal core first, defer safety nets
  • 2190bcd v0.2.0: formalize nondeterminism boundary, harden validation, prioritize core flows
  • 80ce612 Add v0.2.0 release plan and align docs with sources-first ingestion
  • b8c95c2 feat: payload ingestion and observation hardening
  • f907748 Remove data symlink from git tracking
  • 8a67f29 Fix retrieve_records order preservation and update documentation
  • 0670069 Add entity and timeline MCP endpoints, enhance Cursor integration, and update documentation
  • ac2e2be Comprehensive documentation and codebase updates
  • 2c1b61e Comprehensive documentation and infrastructure updates
  • 4ee9a7b Enhance commit command with comprehensive change analysis
  • 229ea54 Major documentation restructure and timeline estimate updates
  • 148e1fa docs: Comprehensive documentation, workflow, and release planning updates
  • 7ea05d8 docs: Comprehensive documentation and workflow improvements
  • cc8f67b feat: restructure docs, add manifest, and refine frontend tooling
  • b1bb143 feat: Add AI-powered record comparison and enhance file upload insights
  • f8178f3 Docs: restructure MVP docs and architecture overview Tests: stabilize UI integration against missing frontend/backend Chore: ignore local data and private docs; improve SSL debug scripts
  • 9b0181b feat: add branch-based domain routing with HTTPS support
  • 1fc4d72 Merge branch 'feat/playwright-coverage-worktree'
  • 701b40d refactor: migrate commit command to user-level
  • 058595b Merge remote-tracking branch 'origin/feat/playwright-100-percent-coverage' into feat/playwright-100-percent-coverage
  • 16a8484 chore: harden commit workflow and dev serve helpers
  • 30a2051 fix: stabilize ui tests
  • 0c9cf48 feat: achieve 100% Playwright test coverage across functional, state, and component dimensions
  • 93050d7 feat: achieve 100% Playwright test coverage across functional, state, and component dimensions
  • fa594c3 Fix WebSocket port discovery and improve error handling
  • c3c6a42 Merge branch 'fix-debug-issue-gpENr' into dev
  • 0d12f01 feat: implement fuzzy matching for record searches and fix chat query discrepancies
  • 6cedbb2 Merge remote-tracking branch 'origin/feat/playwright-test-coverage' into dev
  • 9a683d9 feat: add comprehensive Playwright end-to-end test coverage
  • d789da4 Merge branch 'chat-20251118-140748-044d41' into dev
  • d9662cb test(e2e): add Playwright harness and server fixtures
  • 514fbba chore(cursor): move commands and rules out of repo
  • 4277753 feat(records): dynamic property columns and dev tooling
  • 3d8f694 Align Plaid normalizer expectations with machine-case props
  • d1169b2 feat: add worktree support to merge-dev script
  • eae2780 feat: restore chat intro message, fix key change detection, and improve AI query behavior
  • 3b1b890 Stabilize dev env tests and oauth state
  • 443e536 feat: add connectors platform and modern records workspace
  • 3c4a01c feat: align grooming tools and docs
  • 576ba04 fix: improve error handling and API configuration for file uploads
  • e75df73 Merge branch 'test/convert-ui-integration-test-stubs' into dev
  • 644ccee docs: update merge command to switch to dev after merge
  • 45ecc14 Merge branch 'test/convert-ui-integration-test-stubs' into dev
  • 3e9bf2d feat: enhance file processing, error handling, and UI improvements
  • 367a99c Merge test/convert-ui-integration-test-stubs into dev
  • 8e18735 chore: switch license from ISC to MIT
  • 809121a test: Convert UI integration test stubs to executable tests
  • 64421c0 feat: Add summary field to records with AI-generated summaries
  • 1a73db1 feat: Add merge command to merge current branch into dev
  • 16cab5a feat: Add chat-specific branch management with automatic renaming
  • 12d3fc5 docs: improve commit command instructions to prevent missing changes
  • 8e4bca9 feat: implement local-first end-to-end encrypted datastore architecture
  • 730ddef feat: migrate UI to React with shadcn
  • fabd232 Update README with chat endpoint in API spec table
  • 751a1cf Add chat interface with OpenAI function calling for record queries
  • 99150f9 Add Plaid integration, API sandbox UI, and security logging improvements
  • 79285c8 WIP: CSV uploader with normalization and LLM transforms
  • dc11c6d Initial commit: MCP server for extensible record storage with semantic search, ChatGPT Actions, and Supabase backend

Full compare: v0.4.0...v0.4.1

v0.4.0 Breaking risk
Notable features
  • 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.10v0.4.0view 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 info is clearer and more script-friendly, with explicit environment context, absolute local paths, and a stronger nudge toward --json for stable automation.
  • CLI argument handling is more reliable when Neotoma is invoked through node, bun, or deno wrappers. The extractUserCliArgs change 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.yaml and the generated dist/ 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.10 and 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, and src/cli/index.ts.
  • The current dev work also removes the older llm_extraction path 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-auth Vite 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.0 because v0.3.11 never shipped to npm.
  • The currently intended scope includes semver-significant work: removal of the old llm_extraction path, larger server/action refactors, and OpenAPI churn. That is why this release is being prepared as minor 0.4.0 rather than a patch.
  • For users coming from 0.3.10, also review the unpublished v0.3.11 narrative because its CLI and runtime changes are expected to land in the same next npm release.

Commits (v0.3.10v0.4.0)

  • 65d0bc6 build(site): refresh prerendered export for v0.4.0
  • 1c355b9 docs(release): refresh v0.4.0 supplement for final site fixes
  • 5df815b fix(site): improve dark-surface copy contrast
  • 7dddd47 fix(site): align intro section edge indicators
  • 14174f8 chore: remove repo-root clutter (tracked branch-ports state, npm pack artifact)
  • 1048479 docs: update foundation submodule for release guidance
  • 2ffbff0 refine evaluation-first site flow and public release notes
  • 55b5df2 docs(release): prepare v0.4.0 notes and versioning
  • 6db15c5 Update marketing site navigation, scroll UX, analytics, and subpages
  • 5aaf17f fix: track DatabaseMemoryPage for Vite build (gitignore data* clash)
  • fe5900c Update marketing site, repo metadata, SEO, analytics, and home IA
  • aa7bcca docs(site): ICP paths, marketing pages, workflows, and site export refresh
  • 715673d Add site marketing pages, markdown hub, and SEO dev tooling
  • 675c70a chore(docs): bump docs/private submodule (Isaac CD trilogy + persona)
  • 9e6c0e1 feat(site): healthcare, gov, customer-ops, logistics verticals; private doc submodule
  • d818180 refine(site): vertical landing shell UX and agent-auth page
  • a1ae104 fix(site): ship AgentAuthLandingPage and full-page segment for /agent-auth
  • dddd291 feat(site): vertical index + landings, marketing full-page shell
  • d0a268a ci(dev-pages): install Playwright Chromium before site prerender build
  • 649003c feat(site): CRM/compliance verticals, timeline/schema, docs, scripts
  • af9be62 Release v0.3.11: site, docs, MCP/ChatGPT integration

Full compare: v0.3.10...v0.4.0

v0.3.11 Breaking risk
Notable features
  • 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.10v0.3.11view 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 in docs/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 --json stays the global JSON output flag.
  • storage merge-db: merge SQLite DBs with --source / --target, conflict modes safe (default) | keep-target | keep-source, --dry-run, optional --no-recompute-snapshots. Documented in CLI reference.
  • sync_mcp_configs script and related config wiring updated for current MCP layouts.

HTTP Actions / in-process API (dist/)

  • Substantial updates to src/actions.ts and 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 via dist/.

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.ts and 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.yaml shipped in the package files list 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 ships openapi.yaml only unless package.json files is 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 in store, create_relationship + EMBEDS clarification, external-tool and research deliverable store-first rules, entity-type consistency for imports, CLI parity (search / store aliases), 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 — batched store + relationships example; mcp_chatgpt_setup.md — points ChatGPT Apps connector readers to chatgpt_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.ts and openapi.yaml evolved together with the action handlers.
  • New docs/developer/chatgpt_integration_instructions.md and 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-db defaults to safe mode to avoid silent data loss—call that out to operators merging databases.

Commits (v0.3.10v0.3.11)

  • af9be62 Release v0.3.11: site, docs, MCP/ChatGPT integration

Full compare: v0.3.10...v0.3.11

v0.3.10 Bug fix

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.yaml is 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)

  • 0f38c88 Prepare v0.3.10 patch release metadata.
  • 79bae79 Fix SEO title on basename-root detail pages.
  • 030a79b Install Playwright Chromium in Pages deploy workflow.
  • dbafcfb Add build-time prerendering for GitHub Pages SEO.
  • e20fc6f Update install page content.
  • 66aaa5f Update localized site loading and docs navigation.
  • 7883f03 Commit outstanding docs, frontend, and generated site updates.
  • 1443b2a Fix docs UI icon wiring and guarantee table runtime regression.
  • 25c0f10 Merge branch 'dev'.
  • b7fd822 Record local main-branch updates before merge.
  • 10e2006 Update docs site cards, icons, and integration walkthrough content.
  • eeecda3 Fix intermittent intro invisibility on dev homepage.
  • b8c1a08 Fix blank home sections on dev site by relaxing fade-in visibility gating.
  • 73d833e Update site content, navigation, and integration walkthrough pages on dev.
  • ae9c3c8 Restore site redesign/assets and expanded landing subpages after rebase recovery.
  • 68316d7 Update site content and isolate dev Pages deployment.
  • cf98425 Fix dev site build by removing stale route and fallback missing card images.
  • d30938b Replace missing site illustration assets with stable fallback image.
  • e3bafd0 Fix dev deploy lockfile mismatch and widen guarantees section.
  • 7af1b3e Update site content and isolate dev Pages deployment.
  • bccfb9c Overhaul docs and site architecture for expanded multilingual navigation.
  • c03f8f8 Revert GitHub Pages content to v0.3.8.

Full diff: v0.3.9...v0.3.10

v0.3.9 New feature
Notable features
  • 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.
v0.3.8 Bug fix

Minor fixes and improvements.

Full changelog

Highlights

  • Fix npm package install resilience by shipping openapi.yaml and 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 neotoma in 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

  • vitest suite executed via pre-commit hooks during release commit.
  • Targeted contract and regression tests passed locally, including OpenAPI install resilience and stdio logging safety.
v0.3.7 Bug fix

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
v0.3.6 New feature
⚠ Upgrade required
  • No manual migration steps required for typical installs.
  • If you use custom CLI initialization flows, review updated init behavior and CLI docs.
Notable features
  • 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

v0.3.5 Maintenance
Notable features
  • 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.
v0.3.4 Bug fix

Fixed pagination and total count inconsistency for deleted tasks.

Full changelog

Highlights

  • Fix retrieve_entities for entity_type: \"task\" to paginate after deleted-entity filtering.
  • Align total with visible (non-deleted) entities so pagination offsets remain consistent.
  • Add regression coverage for task pagination/count consistency.

Included changes

  • src/services/entity_queries.ts
  • src/shared/action_handlers/entity_handlers.ts
  • tests/integration/mcp_entity_variations.test.ts
v0.3.3 Breaking risk

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

  • neotoma commands 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.3 branch. GitHub Pages deploy workflow remains untouched because no push to main was performed.
v0.3.2 Breaking risk

Minor fixes and improvements.

Full changelog

What Changed

CLI and Initialization Reliability

  • Fixed neotoma init behavior to correctly create .env when 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.tsx
    • frontend/src/site/site_data.ts
    • frontend/src/site/seo_metadata.ts
    • frontend/index.html
    • frontend/docs.html
    • scripts/build_github_pages_site.tsx
    • docs/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.ts
    • src/services/mcp_auth.ts, src/services/mcp_oauth.ts
    • src/services/field_validation.ts, src/services/field_converters.ts
    • src/services/parquet_reader.ts, src/services/public_key_registry.ts
    • src/crypto/auth.ts

Packaging and Release Hygiene

  • Updated package metadata/version state in package.json and package-lock.json.
  • Updated release/deployment docs and status artifacts.

Behavior Changes

  • neotoma init now more reliably creates and reports .env setup outcomes.
  • Running neotoma without 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 .env creation 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.
v0.3.1 Breaking risk
Notable features
  • 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 during neotoma init and startup flows.
  • Expanded environment defaults in .env.example to better align local setup with current runtime expectations.

Frontend and App Boot

  • Updated frontend boot wiring in frontend/src/main.tsx and frontend/src/components/MainApp.tsx.
  • Added analytics utility support in frontend/src/utils/analytics.ts and related typings in frontend/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.js
    • scripts/cloudflare_ensure_caa_letsencrypt.sh
    • scripts/cloudflare_set_dns_only.sh
    • scripts/cloudflare_set_github_pages_apex.sh
    • scripts/remove_cloudflare_redirect.sh
  • Updated deployment guidance in docs/infrastructure/deployment.md.

Packaging and Dependency State

  • Updated package.json and package-lock.json for release packaging and dependency alignment.
  • Updated rule-distribution copies for CLI instructions (.cursor, .claude, .codex).

Behavior Changes

  • neotoma startup 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.
v0.3.0 Breaking risk
Notable features
  • 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 dev to main.
  • Canonical site URLs move from https://markmhendrickson.github.io/neotoma/ to https://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 main publishing and direct neotoma.io serving.
  • 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 with https://neotoma.io in:
    • frontend site metadata
    • frontend/public/site_pages index.html
    • robots/sitemap files
    • SEO unit tests

Tests and verification

  • tests/unit/seo_metadata.test.ts passes with updated canonical domain.
  • Full test suite pass: 89 test files passed, 2 skipped; 1054 tests passed, 12 skipped.
  • npm run simulate:install passes 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 whoami currently returns 401 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

  1. Confirm this version and notes.
  2. Fix npm auth, publish v0.3.0.
  3. Merge dev to main.
  4. Verify Pages deploy from main.
  5. Tag v0.3.0 and create GitHub release.

Beta — feedback welcome: [email protected]