neotoma 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +91 -11
- package/dist/actions.js.map +1 -1
- package/dist/cli/harness_configure.d.ts +2 -1
- package/dist/cli/harness_configure.d.ts.map +1 -1
- package/dist/cli/harness_configure.js.map +1 -1
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +52 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp_config_scan.d.ts +29 -0
- package/dist/cli/mcp_config_scan.d.ts.map +1 -1
- package/dist/cli/mcp_config_scan.js +35 -6
- package/dist/cli/mcp_config_scan.js.map +1 -1
- package/dist/cli/setup.d.ts +24 -3
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +65 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/docs/conventions/documentation_standards.md +1 -1
- package/dist/docs/developer/atomic_corrections.md +2 -2
- package/dist/docs/developer/cli_agent_instructions.md +11 -2
- package/dist/docs/developer/cli_reference.md +10 -1
- package/dist/docs/developer/mcp/instructions.md +7 -2
- package/dist/docs/security/advisories/2026-11-04-peer-sync-and-agent-grant-scope.md +41 -0
- package/dist/docs/security/advisories/README.md +1 -0
- package/dist/docs/testing/automated_test_catalog.md +32 -19
- package/dist/inspector/assets/{access_policies-CxCjBA7D.js → access_policies-CecrDHE5.js} +1 -1
- package/dist/inspector/assets/{agent_badge-DC5_shpm.js → agent_badge-bFKcTLc3.js} +1 -1
- package/dist/inspector/assets/{agent_detail-BvbCiS93.js → agent_detail-ByxqvVXp.js} +1 -1
- package/dist/inspector/assets/{agent_filter-B0yydBrx.js → agent_filter-CIlnJqXp.js} +1 -1
- package/dist/inspector/assets/{agent_grant_detail-3kKIKzX6.js → agent_grant_detail-BS9vi68s.js} +1 -1
- package/dist/inspector/assets/{agent_grant_form-B6q5pZjP.js → agent_grant_form-CUNvJrPS.js} +1 -1
- package/dist/inspector/assets/{agent_grants-B6nfERyL.js → agent_grants-DKd7ld_4.js} +1 -1
- package/dist/inspector/assets/{agents-ClGGY_ZM.js → agents-CE6YYOPn.js} +1 -1
- package/dist/inspector/assets/{api_not_configured_state-CJQ8_tf0.js → api_not_configured_state-BdXbCQAz.js} +1 -1
- package/dist/inspector/assets/{attribution_card-Bksgj8a3.js → attribution_card-Df6GMziR.js} +1 -1
- package/dist/inspector/assets/{attribution_summary-D4MXp_WI.js → attribution_summary-B2T-E3h9.js} +1 -1
- package/dist/inspector/assets/{bundles-ycjhJZOr.js → bundles-DPrW5kwK.js} +1 -1
- package/dist/inspector/assets/{card-4DFCisoq.js → card-xB0wTMgy.js} +1 -1
- package/dist/inspector/assets/{checkbox-V-L1QbzC.js → checkbox-C6aOTIf3.js} +1 -1
- package/dist/inspector/assets/{compliance-DKt8M8nA.js → compliance-CKOQJGVG.js} +1 -1
- package/dist/inspector/assets/{confirm-dialog-DYa8Vbqn.js → confirm-dialog-CrSwx0Db.js} +1 -1
- package/dist/inspector/assets/{conversation_common-BTYeAMA9.js → conversation_common-C5W4gEXW.js} +1 -1
- package/dist/inspector/assets/{conversation_detail-CW7GDcOq.js → conversation_detail-Uz4wDgPf.js} +1 -1
- package/dist/inspector/assets/{copy_id_button-ByAabH9A.js → copy_id_button-CDMxVOzU.js} +1 -1
- package/dist/inspector/assets/{copyable_code_block-Bspyx1dk.js → copyable_code_block-CPl0aWFe.js} +1 -1
- package/dist/inspector/assets/{corrections-CTmXBVDZ.js → corrections-Dwj1Fugu.js} +1 -1
- package/dist/inspector/assets/{dashboard-C4yk5lEb.js → dashboard-BBCSRZNU.js} +1 -1
- package/dist/inspector/assets/{data-table-BWQDz2No.js → data-table-aUtH1nlD.js} +1 -1
- package/dist/inspector/assets/{design-DSwT0Hqn.js → design-D0gJ9iB8.js} +1 -1
- package/dist/inspector/assets/{dialog-D-_2M8D7.js → dialog-CMWtV0zN.js} +1 -1
- package/dist/inspector/assets/{docs-BcccV5pq.js → docs-Byar2vOe.js} +1 -1
- package/dist/inspector/assets/{docs_page_layout-D2iWK6hY.js → docs_page_layout-CP64UQbJ.js} +1 -1
- package/dist/inspector/assets/{embed_graph-BjqqvjAi.js → embed_graph-CnaGuKds.js} +1 -1
- package/dist/inspector/assets/{empty_state-DWHf3FCX.js → empty_state-BzT7NRtZ.js} +1 -1
- package/dist/inspector/assets/{entities-DrG0hlC7.js → entities-fkG18fss.js} +1 -1
- package/dist/inspector/assets/{entity_correct-Bpg1q7T4.js → entity_correct-mnPBHieg.js} +1 -1
- package/dist/inspector/assets/{entity_history-CJ62iQZu.js → entity_history-Th7OnpfA.js} +1 -1
- package/dist/inspector/assets/{entity_history_sections-BDd9Wiiu.js → entity_history_sections-DwEU4Y5F.js} +1 -1
- package/dist/inspector/assets/{entity_link-Bb0aaVN-.js → entity_link-U1JSr9H2.js} +1 -1
- package/dist/inspector/assets/{entity_relationships_by_type-CJyxm8EQ.js → entity_relationships_by_type-B6ZTLPGk.js} +1 -1
- package/dist/inspector/assets/{entity_segment_page-q21vDqLO.js → entity_segment_page-N7j8YJxA.js} +1 -1
- package/dist/inspector/assets/{entity_table_column_toggle-DN8xVqKP.js → entity_table_column_toggle-DfKBCgU2.js} +1 -1
- package/dist/inspector/assets/{entity_timeline-D8glraS3.js → entity_timeline-B7sMnfd3.js} +1 -1
- package/dist/inspector/assets/{entity_types-Cers3ITY.js → entity_types-D5la65Sn.js} +1 -1
- package/dist/inspector/assets/{faq-Bd-NrqaV.js → faq-C-BJiIWQ.js} +1 -1
- package/dist/inspector/assets/{graph_auto_fit-BYwV350M.js → graph_auto_fit-Cl1sM7g6.js} +1 -1
- package/dist/inspector/assets/{graph_explorer-LCTji9_2.js → graph_explorer-BF8NyJLR.js} +1 -1
- package/dist/inspector/assets/home-Czrx0JG4.js +1 -0
- package/dist/inspector/assets/{index-B6DF8LVA.js → index-BcN-bmX4.js} +2 -2
- package/dist/inspector/assets/{index-Cb4wreu4.js → index-Bf45K-hH.js} +1 -1
- package/dist/inspector/assets/{index-gMZogIZg.js → index-DnnkhCRn.js} +1 -1
- package/dist/inspector/assets/{interpretations-Cy0Bpx62.js → interpretations-BON8Hv6B.js} +1 -1
- package/dist/inspector/assets/interpretations-D1AiR24H.js +1 -0
- package/dist/inspector/assets/{issue_author_attribution-DcQIow4F.js → issue_author_attribution-BiIemiwE.js} +1 -1
- package/dist/inspector/assets/{issue_detail-DTjIEgh0.js → issue_detail-DKwqgprb.js} +1 -1
- package/dist/inspector/assets/{issues-Dphlhv_W.js → issues-DN0qXAD9.js} +1 -1
- package/dist/inspector/assets/{json_viewer-BM4kmWFP.js → json_viewer-o1fpEDum.js} +1 -1
- package/dist/inspector/assets/{label-hdmBvRvv.js → label-6dQuJkiv.js} +1 -1
- package/dist/inspector/assets/{live_relative_time-CYFW3IVl.js → live_relative_time-DRapJJqL.js} +1 -1
- package/dist/inspector/assets/{mobile_filter_popover-KCC5eTUH.js → mobile_filter_popover-CG_CrM1J.js} +1 -1
- package/dist/inspector/assets/{not_found-NNkEa9Mr.js → not_found-ZFJp_piF.js} +1 -1
- package/dist/inspector/assets/{oauth_callback-Vg8huIE7.js → oauth_callback-0LtMaQug.js} +1 -1
- package/dist/inspector/assets/{oauth_signin-DgBwjyyR.js → oauth_signin-Dojz-oXP.js} +1 -1
- package/dist/inspector/assets/{observations-DtOGIRUt.js → observations-L18GAXwN.js} +1 -1
- package/dist/inspector/assets/{page_shell-ekehM_7R.js → page_shell-DGmu9DSu.js} +1 -1
- package/dist/inspector/assets/{pagination-DqHnb2pk.js → pagination-D06zx3An.js} +1 -1
- package/dist/inspector/assets/{peer_detail-Gkxcd75E.js → peer_detail-ChA0ildZ.js} +1 -1
- package/dist/inspector/assets/{peers-CbWw6lyc.js → peers-1DpY9nuL.js} +1 -1
- package/dist/inspector/assets/{pin_primitive_button-B4r-7dqY.js → pin_primitive_button-C69_BXo8.js} +1 -1
- package/dist/inspector/assets/{recent_activity-C6PVuidG.js → recent_activity-_tzwJHSQ.js} +1 -1
- package/dist/inspector/assets/{recent_conversations-CIdElm4H.js → recent_conversations-DIuO8UEC.js} +1 -1
- package/dist/inspector/assets/{recent_conversations-D0yaACqZ.js → recent_conversations-DyySBTfu.js} +1 -1
- package/dist/inspector/assets/{recent_records_feed-CIXUCAzn.js → recent_records_feed-C3kqxaSx.js} +1 -1
- package/dist/inspector/assets/record_activity-D6T1ehSh.js +1 -0
- package/dist/inspector/assets/{relationship_detail-Bpefk_R5.js → relationship_detail-DB9gZgOc.js} +1 -1
- package/dist/inspector/assets/{relationship_panel_groups-DDXpEtW5.js → relationship_panel_groups-DDcasdh0.js} +1 -1
- package/dist/inspector/assets/{relationships-B3QrncvI.js → relationships-DE8zWSeh.js} +1 -1
- package/dist/inspector/assets/{relationships-M99riRdd.js → relationships-r726Am6k.js} +1 -1
- package/dist/inspector/assets/{sandbox-DucoYAes.js → sandbox-CK8Xh0zh.js} +1 -1
- package/dist/inspector/assets/{schema_detail-CN_3OF1B.js → schema_detail-tV9qZlDI.js} +1 -1
- package/dist/inspector/assets/{schemas-rRFQFZKI.js → schemas-r5vde1ev.js} +1 -1
- package/dist/inspector/assets/{search-CtnCyQ8D.js → search-CYsHQGOl.js} +1 -1
- package/dist/inspector/assets/{segmented_control-DSHm0DuI.js → segmented_control-Dh7hbz4k.js} +1 -1
- package/dist/inspector/assets/{select-DhzhhG8n.js → select-BKEI7cq9.js} +1 -1
- package/dist/inspector/assets/{settings-B7cfSG_W.js → settings-CGFwUgc3.js} +1 -1
- package/dist/inspector/assets/{source_content-Bhwy7rhS.js → source_content-BVWgibsY.js} +1 -1
- package/dist/inspector/assets/{source_content_open_button-C6vUIgFc.js → source_content_open_button-CILzjRlO.js} +1 -1
- package/dist/inspector/assets/{source_detail-C1JXqtvA.js → source_detail-C1w4In3r.js} +1 -1
- package/dist/inspector/assets/{source_link-BUk8ACVx.js → source_link-DlxqKShY.js} +1 -1
- package/dist/inspector/assets/{sources-NTyTD2hT.js → sources-C3c88YnL.js} +1 -1
- package/dist/inspector/assets/{subscriptions-CNA06mS4.js → subscriptions-BJI8nfBi.js} +1 -1
- package/dist/inspector/assets/{switch-DLHM_uAC.js → switch-Dx7yDS8J.js} +1 -1
- package/dist/inspector/assets/{tabs-D2_FUlH4.js → tabs-C7CNmtlx.js} +1 -1
- package/dist/inspector/assets/{textarea-DS0t72g6.js → textarea-CnKEdeS7.js} +1 -1
- package/dist/inspector/assets/{timeline-CVhW-34e.js → timeline-DFvizOXt.js} +1 -1
- package/dist/inspector/assets/{timeline-CZehuTIb.js → timeline-TBibq40-.js} +1 -1
- package/dist/inspector/assets/{timeline_event_detail-KYTlaJ99.js → timeline_event_detail-DXpLKXwn.js} +1 -1
- package/dist/inspector/assets/{turn_detail-DN4VR_ut.js → turn_detail-DxoBBnAV.js} +1 -1
- package/dist/inspector/assets/{turns-Bq8p8bUB.js → turns-DYRndDTk.js} +1 -1
- package/dist/inspector/assets/{use_agents-GVOD0Ky2.js → use_agents-EhoEA4-8.js} +1 -1
- package/dist/inspector/assets/{use_entities-Buvb5BTb.js → use_entities-DzF_NpWe.js} +1 -1
- package/dist/inspector/assets/use_interpretations-CmKAxtHd.js +1 -0
- package/dist/inspector/assets/{use_mutations-DbLUsoYs.js → use_mutations-Da9jgbQb.js} +1 -1
- package/dist/inspector/assets/{use_peers-DyQGh7km.js → use_peers-C1-jKVUX.js} +1 -1
- package/dist/inspector/assets/{use_relationships-djzl2cEw.js → use_relationships-ClEy1YjY.js} +1 -1
- package/dist/inspector/assets/{use_stats-DvaDtejF.js → use_stats-jYkK0Ydj.js} +1 -1
- package/dist/inspector/assets/{use_timeline-BL3A-Im3.js → use_timeline-CNpY1sVJ.js} +1 -1
- package/dist/inspector/assets/{use_turns-DEvDeYgu.js → use_turns-aYgpXeJo.js} +1 -1
- package/dist/inspector/assets/{world_time_event_timeline-DjPxlzYn.js → world_time_event_timeline-4k2EdpBk.js} +1 -1
- package/dist/inspector/index.html +1 -1
- package/dist/repositories/sqlite/sqlite_client.d.ts +13 -1
- package/dist/repositories/sqlite/sqlite_client.d.ts.map +1 -1
- package/dist/repositories/sqlite/sqlite_client.js +26 -0
- package/dist/repositories/sqlite/sqlite_client.js.map +1 -1
- package/dist/repositories/worker/worker_file_database.d.ts +16 -1
- package/dist/repositories/worker/worker_file_database.d.ts.map +1 -1
- package/dist/repositories/worker/worker_file_database.js +280 -29
- package/dist/repositories/worker/worker_file_database.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +28 -7
- package/dist/server.js.map +1 -1
- package/dist/services/bounded_identity_read.d.ts +26 -0
- package/dist/services/bounded_identity_read.d.ts.map +1 -0
- package/dist/services/bounded_identity_read.js +154 -0
- package/dist/services/bounded_identity_read.js.map +1 -0
- package/dist/services/correction_transaction.d.ts.map +1 -1
- package/dist/services/correction_transaction.js +9 -3
- package/dist/services/correction_transaction.js.map +1 -1
- package/dist/services/current_state_reads.d.ts +56 -0
- package/dist/services/current_state_reads.d.ts.map +1 -0
- package/dist/services/current_state_reads.js +337 -0
- package/dist/services/current_state_reads.js.map +1 -0
- package/dist/services/entity_population_certificate.d.ts.map +1 -1
- package/dist/services/entity_population_certificate.js +27 -16
- package/dist/services/entity_population_certificate.js.map +1 -1
- package/dist/services/entity_queries.d.ts +0 -5
- package/dist/services/entity_queries.d.ts.map +1 -1
- package/dist/services/entity_queries.js +296 -316
- package/dist/services/entity_queries.js.map +1 -1
- package/dist/services/mcp_lookup_timing.d.ts +25 -0
- package/dist/services/mcp_lookup_timing.d.ts.map +1 -0
- package/dist/services/mcp_lookup_timing.js +156 -0
- package/dist/services/mcp_lookup_timing.js.map +1 -0
- package/dist/services/request_context.d.ts +3 -0
- package/dist/services/request_context.d.ts.map +1 -1
- package/dist/services/request_context.js.map +1 -1
- package/dist/services/schema_registry.d.ts +29 -11
- package/dist/services/schema_registry.d.ts.map +1 -1
- package/dist/services/schema_registry.js +193 -58
- package/dist/services/schema_registry.js.map +1 -1
- package/dist/shared/action_handlers/exact_identity_read.d.ts +8 -0
- package/dist/shared/action_handlers/exact_identity_read.d.ts.map +1 -0
- package/dist/shared/action_handlers/exact_identity_read.js +67 -0
- package/dist/shared/action_handlers/exact_identity_read.js.map +1 -0
- package/dist/shared/action_schemas.d.ts +19 -12
- package/dist/shared/action_schemas.d.ts.map +1 -1
- package/dist/shared/action_schemas.js +14 -3
- package/dist/shared/action_schemas.js.map +1 -1
- package/dist/shared/contract_mappings.d.ts.map +1 -1
- package/dist/shared/contract_mappings.js +1 -0
- package/dist/shared/contract_mappings.js.map +1 -1
- package/dist/shared/openapi_types.d.ts +100 -3
- package/dist/shared/openapi_types.d.ts.map +1 -1
- package/dist/shared/schema_planning.d.ts +24 -0
- package/dist/shared/schema_planning.d.ts.map +1 -0
- package/dist/shared/schema_planning.js +22 -0
- package/dist/shared/schema_planning.js.map +1 -0
- package/dist/tool_definitions.d.ts.map +1 -1
- package/dist/tool_definitions.js +15 -29
- package/dist/tool_definitions.js.map +1 -1
- package/docs/developer/mcp/instructions.md +7 -2
- package/openapi.yaml +143 -4
- package/package.json +3 -3
- package/skills/continue-session/SKILL.md +547 -0
- package/skills/end/SKILL.md +3 -1
- package/skills/status/SKILL.md +302 -80
- package/skills/where/SKILL.md +36 -30
- package/dist/inspector/assets/home-EisPy9sH.js +0 -1
- package/dist/inspector/assets/interpretations-BGaVaB-X.js +0 -1
- package/dist/inspector/assets/record_activity-BjhZYy74.js +0 -1
- package/dist/inspector/assets/use_interpretations-DDEREnBJ.js +0 -1
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ graph LR
|
|
|
61
61
|
|
|
62
62
|
## What you can do with it
|
|
63
63
|
|
|
64
|
-
Neotoma v0.
|
|
64
|
+
Neotoma v0.28.0 exposes 67 MCP tools and 112 REST paths in its OpenAPI spec. They cover largely the same capabilities, but the MCP server, the REST API, and the CLI are separate implementations, and some checks and attribution differ between them (see Known limitations). The capability surface includes:
|
|
65
65
|
|
|
66
66
|
**Ingest and store.** Store structured records or raw files in one call. File ingestion extracts text from PDF (with a first-page image fallback), CSV (with adaptive chunking for large files), Parquet, JSON, and plain text; images and audio are stored as raw sources. A committed, keyed structured store started on v0.26.0 that stops partway finishes its missing observations on a same-key retry; a store carrying an interpretation returns `ERR_STORE_WRITE_INCOMPLETE`, and keys left over from earlier versions behave differently over MCP and HTTP (see Known limitations). See Known limitations.
|
|
67
67
|
|
|
@@ -111,12 +111,12 @@ neotoma init
|
|
|
111
111
|
neotoma setup --tool claude-code
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
In
|
|
114
|
+
In the current package source, `neotoma setup --tool claude-code` writes the MCP entries and more. The skill count below includes source changes not yet in published v0.27.0, which contains 12 installable skills; check the package version you actually use:
|
|
115
115
|
|
|
116
116
|
- Two MCP entries in the project's `.mcp.json`: `neotoma-dev` (development profile, `neotoma.db`) and `neotoma` (production profile, `neotoma.prod.db`). They use separate databases, so an agent on one entry does not see what an agent on the other stored.
|
|
117
117
|
- CLI instruction files for Claude Code, Cursor, and Codex in the project: `.claude/rules/neotoma_cli.mdc`, `.cursor/rules/neotoma_cli.mdc`, and `.codex/neotoma_cli.md`.
|
|
118
118
|
- When `claude` is on your PATH, it runs `claude plugin marketplace add` and `claude plugin install` to install the Neotoma Claude Code plugin (five hooks). Without `claude` on PATH, setup writes everything else and then exits with status 1.
|
|
119
|
-
- When `~/.claude` exists, it links
|
|
119
|
+
- When `~/.claude` exists, it links 13 Neotoma skills into `~/.claude/skills`.
|
|
120
120
|
|
|
121
121
|
It also adds two allow rules, `Bash(neotoma:*)` and `Bash(npm install -g neotoma:*)`, to `.claude/settings.local.json` (project scope, the default). The first is a wildcard: Claude Code then runs any `neotoma` command without asking, including destructive ones such as `neotoma reset`, `neotoma storage merge-db`, `neotoma backup restore`, and `neotoma processes kill`. `--scope both` also writes the rules to `~/.claude/settings.json`, and `--skip-permissions` writes none. For Cursor the same two rules go to `.cursor/allowlist.json`; for Codex they go to the user-level `~/.codex/config.toml` whatever the scope.
|
|
122
122
|
|
|
@@ -165,7 +165,7 @@ As agent use expands, reality fragments across chat histories, agent memories, f
|
|
|
165
165
|
|
|
166
166
|
| Vision phase | What it means | Status |
|
|
167
167
|
| --- | --- | --- |
|
|
168
|
-
| **P0: Deterministic single-writer state** | Observations the write path does not edit, hash-derived entity IDs, deterministic reduction, field-level provenance, corrections as new observations, per-entity observation history | ✅ **Shipped**: in daily use; a
|
|
168
|
+
| **P0: Deterministic single-writer state** | Observations the write path does not edit, hash-derived entity IDs, deterministic reduction, field-level provenance, corrections as new observations, per-entity observation history | ✅ **Shipped**: in daily use; a correction stays authoritative on its field until a later correction replaces it |
|
|
169
169
|
| **P1: Multi-user state foundations** | Human and agent identities, attributed writes, tenant isolation, access controls, shared instances | 🟡 **Partially shipped**: hosted multi-user mode with `user_id` tenancy, per-agent identity (AAuth, optional hardware attestation), capability grants, guest tokens, peer federation. Not yet: organizations/workspaces, membership lifecycle, invitations, offboarding |
|
|
170
170
|
| **P2: Authority over state** | Domain ownership, correction rights, supersession, policy ownership, temporary grants, disclosure logs | 🟡 **Mechanisms exist** (corrections, `SUPERSEDES` relationships, per-operation access controls); authority *semantics* (who may correct what, scoped by domain) are future work |
|
|
171
171
|
| **P3: Multi-principal semantics** | Competing interpretations, disputed claims, official positions, consensus vs unresolved disagreement, field-level policies, historical validity | 🔜 Planned: interpretations are first-class today; dispute/official-position semantics are not |
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,wBAAwB,EAE9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,OAAO,MAAM,SAAS,CAAC;AA2C9B,OAAO,EAIL,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAgB3C,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/actions.js
CHANGED
|
@@ -46,6 +46,7 @@ import { IssueTransportError, IssueValidationError } from "./services/issues/err
|
|
|
46
46
|
import { externalActorFromCallerInput } from "./services/issues/external_actor_builder.js";
|
|
47
47
|
import { getCurrentAAuthAdmission, getCurrentAgentIdentity, getCurrentAttribution, getCurrentExternalActor, runWithAuthenticatedPrincipal, runWithExternalActor, runWithRequestContext, } from "./services/request_context.js";
|
|
48
48
|
import { assertCanWriteProtectedBatch } from "./services/protected_entity_types.js";
|
|
49
|
+
import { createMcpLookupReceiptObserver, observeMcpLookupResponse, } from "./services/mcp_lookup_timing.js";
|
|
49
50
|
import { redactMemberAttribution } from "./services/attribution_redaction.js";
|
|
50
51
|
import { createAgentIdentity as buildAgentIdentity, getAgentIdentityFromRequest, normaliseClientName, } from "./crypto/agent_identity.js";
|
|
51
52
|
import { initServerKeys } from "./services/encryption_service.js";
|
|
@@ -81,6 +82,7 @@ import { AnalyzeSchemaCandidatesRequestSchema, AuditUndeclaredFragmentsRequestSc
|
|
|
81
82
|
import { DEFAULT_OBSERVATION_SOURCE } from "./services/observation_insert.js";
|
|
82
83
|
import { getMimeTypeFromExtension } from "./services/file_text_extraction.js";
|
|
83
84
|
import { queryEntitiesWithCount } from "./shared/action_handlers/entity_handlers.js";
|
|
85
|
+
import { EXACT_IDENTITY_REQUEST_MESSAGE, exactIdentityRequested, readExactIdentity, } from "./shared/action_handlers/exact_identity_read.js";
|
|
84
86
|
import { retrieveEntityByIdentifierWithFallback } from "./shared/action_handlers/entity_identifier_handler.js";
|
|
85
87
|
import { prepareEntitySnapshotWithEmbedding, upsertEntitySnapshotWithEmbedding, } from "./services/entity_snapshot_embedding.js";
|
|
86
88
|
import { isNeotomaEntityId } from "./shared/neotoma_entity_id.js";
|
|
@@ -110,6 +112,9 @@ export function getResolvedServerMode() {
|
|
|
110
112
|
return _resolvedServerMode;
|
|
111
113
|
}
|
|
112
114
|
export const app = express();
|
|
115
|
+
const mcpLookupReceiptObserver = createMcpLookupReceiptObserver();
|
|
116
|
+
if (mcpLookupReceiptObserver)
|
|
117
|
+
app.use(mcpLookupReceiptObserver);
|
|
113
118
|
// Trust proxy headers (required for express-rate-limit when X-Forwarded-For is present)
|
|
114
119
|
app.set("trust proxy", true);
|
|
115
120
|
// Configure CSP to allow CDN scripts for the uploader and API connects
|
|
@@ -232,7 +237,10 @@ app.use(express.json({
|
|
|
232
237
|
req.rawBody = Buffer.from(buf);
|
|
233
238
|
},
|
|
234
239
|
}));
|
|
235
|
-
app.use(morgan("dev"
|
|
240
|
+
app.use(morgan("dev", {
|
|
241
|
+
// Suppress identity-bearing URLs independently of route spelling or method.
|
|
242
|
+
skip: (req) => exactIdentityRequested(req.query),
|
|
243
|
+
}));
|
|
236
244
|
app.use(cookieParser());
|
|
237
245
|
app.use(unknownFieldsGuard);
|
|
238
246
|
// Sandbox-mode response header. Stamped on every response so clients can
|
|
@@ -1764,6 +1772,7 @@ app.all("/mcp", async (req, res) => {
|
|
|
1764
1772
|
const authHeader = (req.headers["authorization"] || req.headers["Authorization"]);
|
|
1765
1773
|
let connectionIdHeader = (req.headers["x-connection-id"] || req.headers["X-Connection-Id"]);
|
|
1766
1774
|
let bearerValidated = false;
|
|
1775
|
+
let primaryBearerValidated = false;
|
|
1767
1776
|
// Development connection identities are assigned by this gate, not by the
|
|
1768
1777
|
// client. A client-sent value is honoured only where the gate would assign
|
|
1769
1778
|
// the same identity itself: a local caller in development mode. Anywhere
|
|
@@ -1812,6 +1821,7 @@ app.all("/mcp", async (req, res) => {
|
|
|
1812
1821
|
// same grants. See src/services/bearer_slots.ts.
|
|
1813
1822
|
const slot = matchConfiguredBearer(token);
|
|
1814
1823
|
if (slot) {
|
|
1824
|
+
primaryBearerValidated = slot === "primary";
|
|
1815
1825
|
if (slot === "previous") {
|
|
1816
1826
|
recordPreviousBearerUse({
|
|
1817
1827
|
surface: "mcp",
|
|
@@ -1981,6 +1991,8 @@ app.all("/mcp", async (req, res) => {
|
|
|
1981
1991
|
return res.status(shaped.status).json(shaped.body);
|
|
1982
1992
|
}
|
|
1983
1993
|
// Legacy session path (2025-11-25 and earlier). Unchanged by #2070.
|
|
1994
|
+
// A qualified lookup can disconnect while stale-session recovery is still pending.
|
|
1995
|
+
const mcpLookupTiming = primaryBearerValidated ? observeMcpLookupResponse(req, res) : undefined;
|
|
1984
1996
|
// Get or create transport
|
|
1985
1997
|
let transport = sessionId ? mcpTransports.get(sessionId) : undefined;
|
|
1986
1998
|
let serverInstance = sessionId
|
|
@@ -2118,6 +2130,7 @@ app.all("/mcp", async (req, res) => {
|
|
|
2118
2130
|
// The gate's resolved connection id: the MCP server reads this, never
|
|
2119
2131
|
// the request's X-Connection-Id header.
|
|
2120
2132
|
mcpConnectionId: connectionIdHeader ?? null,
|
|
2133
|
+
mcpLookupTiming,
|
|
2121
2134
|
}, () => transport.handleRequest(req, res, req.body));
|
|
2122
2135
|
}
|
|
2123
2136
|
catch (error) {
|
|
@@ -2188,13 +2201,18 @@ function redactSensitiveFields(obj) {
|
|
|
2188
2201
|
}
|
|
2189
2202
|
return redacted;
|
|
2190
2203
|
}
|
|
2204
|
+
function redactEntityReadInput(value) {
|
|
2205
|
+
return exactIdentityRequested(value)
|
|
2206
|
+
? { read_mode: "exact_identity" }
|
|
2207
|
+
: redactSensitiveFields(value);
|
|
2208
|
+
}
|
|
2191
2209
|
function logDebug(event, req, extra) {
|
|
2192
2210
|
const safe = {
|
|
2193
2211
|
method: req.method,
|
|
2194
2212
|
path: req.path,
|
|
2195
|
-
query:
|
|
2213
|
+
query: redactEntityReadInput(req.query),
|
|
2196
2214
|
headers: redactHeaders(req.headers),
|
|
2197
|
-
body:
|
|
2215
|
+
body: redactEntityReadInput(req.body),
|
|
2198
2216
|
...(extra ? redactSensitiveFields(extra) : {}),
|
|
2199
2217
|
};
|
|
2200
2218
|
// eslint-disable-next-line no-console
|
|
@@ -2204,9 +2222,9 @@ function logWarn(event, req, extra) {
|
|
|
2204
2222
|
const safe = {
|
|
2205
2223
|
method: req.method,
|
|
2206
2224
|
path: req.path,
|
|
2207
|
-
query:
|
|
2225
|
+
query: redactEntityReadInput(req.query),
|
|
2208
2226
|
headers: redactHeaders(req.headers),
|
|
2209
|
-
body:
|
|
2227
|
+
body: redactEntityReadInput(req.body),
|
|
2210
2228
|
...(extra ? redactSensitiveFields(extra) : {}),
|
|
2211
2229
|
};
|
|
2212
2230
|
// eslint-disable-next-line no-console
|
|
@@ -2234,9 +2252,9 @@ function logError(event, req, error, extra) {
|
|
|
2234
2252
|
const payload = {
|
|
2235
2253
|
method: req.method,
|
|
2236
2254
|
path: req.path,
|
|
2237
|
-
query:
|
|
2255
|
+
query: redactEntityReadInput(req.query),
|
|
2238
2256
|
headers: redactHeaders(req.headers),
|
|
2239
|
-
body:
|
|
2257
|
+
body: redactEntityReadInput(req.body),
|
|
2240
2258
|
error: error instanceof Error
|
|
2241
2259
|
? {
|
|
2242
2260
|
name: error.name,
|
|
@@ -4294,6 +4312,18 @@ function handleApiError(req, res, error, defaultMessage, errorCode = "DB_QUERY_F
|
|
|
4294
4312
|
// (POST body, or query-string params coerced by coerceEntitiesQueryParams).
|
|
4295
4313
|
// REQUIRES AUTHENTICATION - all queries filtered by authenticated user_id.
|
|
4296
4314
|
async function runEntitiesQuery(req, res, rawInput) {
|
|
4315
|
+
if (exactIdentityRequested(rawInput)) {
|
|
4316
|
+
try {
|
|
4317
|
+
const userId = await getAuthenticatedUserId(req);
|
|
4318
|
+
const exact_identity = await readExactIdentity(rawInput, userId);
|
|
4319
|
+
if (!exact_identity)
|
|
4320
|
+
return sendError(res, 400, "VALIDATION_ERROR", EXACT_IDENTITY_REQUEST_MESSAGE);
|
|
4321
|
+
return res.set("Cache-Control", "no-store").json({ exact_identity });
|
|
4322
|
+
}
|
|
4323
|
+
catch (error) {
|
|
4324
|
+
return handleApiError(req, res, error, "Could not verify exact identity");
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4297
4327
|
const parsed = EntitiesQueryRequestSchema.safeParse(rawInput);
|
|
4298
4328
|
if (!parsed.success) {
|
|
4299
4329
|
logWarn("ValidationError:entities_query", req, {
|
|
@@ -4416,6 +4446,8 @@ function coerceEntitiesQueryParams(query) {
|
|
|
4416
4446
|
// `GET /entities?entity_type=...&search=...` no longer hit a 404 and silently
|
|
4417
4447
|
// degrade. REQUIRES AUTHENTICATION - identical user scoping to the POST path.
|
|
4418
4448
|
app.get("/entities", async (req, res) => {
|
|
4449
|
+
if (exactIdentityRequested(req.query))
|
|
4450
|
+
return sendError(res, 400, "VALIDATION_ERROR", "Exact identity requires POST /entities/query.");
|
|
4419
4451
|
return runEntitiesQuery(req, res, coerceEntitiesQueryParams(req.query));
|
|
4420
4452
|
});
|
|
4421
4453
|
// POST /api/entities/query - Query entities with filters
|
|
@@ -4926,7 +4958,42 @@ app.get("/schemas", async (req, res) => {
|
|
|
4926
4958
|
// restricted WHICH entity types appear; it never corrected the version, so
|
|
4927
4959
|
// it could not compensate. `userId` is already required above, so scoping
|
|
4928
4960
|
// here changes no caller's authorization, only the accuracy of the version.
|
|
4929
|
-
const
|
|
4961
|
+
const catalog = await schemaRegistry.listEntityTypesResult(keyword, userId);
|
|
4962
|
+
const allSchemas = catalog.entity_types;
|
|
4963
|
+
const summary = req.query.summary === "true";
|
|
4964
|
+
if (summary) {
|
|
4965
|
+
const selected = filterEntityType
|
|
4966
|
+
? allSchemas.filter((schema) => schema.entity_type === filterEntityType)
|
|
4967
|
+
: allSchemas;
|
|
4968
|
+
const sorted = [...selected].sort((a, b) => a.entity_type.localeCompare(b.entity_type));
|
|
4969
|
+
const page = sorted.slice(offset, offset + limit);
|
|
4970
|
+
const reasons = [...catalog.registry_coverage.reasons];
|
|
4971
|
+
if (filterEntityType)
|
|
4972
|
+
reasons.push("filtered");
|
|
4973
|
+
if (offset !== 0 || page.length !== sorted.length)
|
|
4974
|
+
reasons.push("paginated");
|
|
4975
|
+
const complete = catalog.registry_coverage.state === "complete" && reasons.length === 0;
|
|
4976
|
+
return res.json({
|
|
4977
|
+
schemas: page.map(({ entity_type, schema_version, field_names, planning, planning_error }) => ({
|
|
4978
|
+
entity_type,
|
|
4979
|
+
schema_version,
|
|
4980
|
+
field_count: field_names.length,
|
|
4981
|
+
...(planning ? { planning } : {}),
|
|
4982
|
+
...(planning_error ? { planning_error } : {}),
|
|
4983
|
+
})),
|
|
4984
|
+
total: sorted.length,
|
|
4985
|
+
limit,
|
|
4986
|
+
offset,
|
|
4987
|
+
registry_coverage: {
|
|
4988
|
+
...catalog.registry_coverage,
|
|
4989
|
+
state: complete ? "complete" : "unknown",
|
|
4990
|
+
reasons: [...new Set(reasons)].sort(),
|
|
4991
|
+
returned_count: page.length,
|
|
4992
|
+
exhausted: complete,
|
|
4993
|
+
scope: { ...catalog.registry_coverage.scope, entity_type: filterEntityType || null },
|
|
4994
|
+
},
|
|
4995
|
+
});
|
|
4996
|
+
}
|
|
4930
4997
|
// Filter to only show global schemas (user_id is null) or user-specific schemas for this user
|
|
4931
4998
|
// Also fetch metadata (including icons) for each schema
|
|
4932
4999
|
const { data: dbSchemas, error: dbError } = await db
|
|
@@ -4957,6 +5024,16 @@ app.get("/schemas", async (req, res) => {
|
|
|
4957
5024
|
const paginatedSchemas = sortedSchemas.slice(offset, offset + limit);
|
|
4958
5025
|
return res.json({
|
|
4959
5026
|
schemas: paginatedSchemas,
|
|
5027
|
+
registry_coverage: {
|
|
5028
|
+
...catalog.registry_coverage,
|
|
5029
|
+
state: "unknown",
|
|
5030
|
+
exhausted: false,
|
|
5031
|
+
returned_count: paginatedSchemas.length,
|
|
5032
|
+
reasons: [
|
|
5033
|
+
...new Set([...catalog.registry_coverage.reasons, "legacy_filtered_view"]),
|
|
5034
|
+
].sort(),
|
|
5035
|
+
scope: { ...catalog.registry_coverage.scope, entity_type: filterEntityType || null },
|
|
5036
|
+
},
|
|
4960
5037
|
total: productionSchemas.length,
|
|
4961
5038
|
limit,
|
|
4962
5039
|
offset,
|
|
@@ -8574,12 +8651,14 @@ app.post("/get_entity_snapshot", async (req, res) => {
|
|
|
8574
8651
|
}
|
|
8575
8652
|
// Materialization is derived state. Validate owned current authority before
|
|
8576
8653
|
// serving its row, including restrictive corruption acquisition failures.
|
|
8654
|
+
// The check reads the entity's lifecycle authority rows, not its whole
|
|
8655
|
+
// observation history (#2792).
|
|
8577
8656
|
try {
|
|
8578
|
-
const {
|
|
8657
|
+
const { isOwnedEntityHiddenAfterCutover } = await import("./services/current_state_reads.js");
|
|
8579
8658
|
const { hasRecordedEntityLifecycleCutover } = await import("./services/entity_lifecycle_storage.js");
|
|
8580
8659
|
const { getDb } = await import("./repositories/db/connection.js");
|
|
8581
8660
|
if ((await hasRecordedEntityLifecycleCutover(await getDb())) &&
|
|
8582
|
-
(await
|
|
8661
|
+
(await isOwnedEntityHiddenAfterCutover(entity_id, userId)))
|
|
8583
8662
|
return sendError(res, 404, "RESOURCE_NOT_FOUND", "Entity not found");
|
|
8584
8663
|
}
|
|
8585
8664
|
catch (err) {
|
|
@@ -9872,7 +9951,7 @@ app.post("/update_schema_incremental", async (req, res) => {
|
|
|
9872
9951
|
}
|
|
9873
9952
|
try {
|
|
9874
9953
|
const userId = await getAuthenticatedUserId(req, parsed.data.user_id);
|
|
9875
|
-
const { entity_type, fields_to_add, fields_to_remove, canonical_name_fields, schema_version,
|
|
9954
|
+
const { entity_type, fields_to_add, fields_to_remove, canonical_name_fields, planning, schema_version,
|
|
9876
9955
|
// #2374: no local `= false` default. `user_specific` stays
|
|
9877
9956
|
// `undefined` when the caller omitted it, so `updateSchemaIncremental`
|
|
9878
9957
|
// can defer to whichever scope its own read resolved instead of being
|
|
@@ -9948,6 +10027,7 @@ app.post("/update_schema_incremental", async (req, res) => {
|
|
|
9948
10027
|
// re-key (the MCP server handler had it, but this Express route — which
|
|
9949
10028
|
// the CLI offline transport uses — did not).
|
|
9950
10029
|
canonical_name_fields,
|
|
10030
|
+
planning,
|
|
9951
10031
|
schema_version,
|
|
9952
10032
|
user_specific,
|
|
9953
10033
|
// #2374: pass userId unconditionally — same reasoning as the MCP
|