cortexdbai 0.13.0__tar.gz → 0.14.0__tar.gz
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.
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/COVERAGE.md +68 -11
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/PKG-INFO +625 -14
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/README.md +619 -13
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/__init__.py +1 -1
- cortexdbai-0.14.0/cortexdb/memory_tool.py +601 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/__init__.py +46 -0
- cortexdbai-0.14.0/cortexdb/v1/_blake3.py +91 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/_transport.py +60 -1
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/_wire.py +34 -3
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/auth.py +33 -20
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/client.py +90 -7
- cortexdbai-0.14.0/cortexdb/v1/derivation.py +840 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/errors.py +456 -36
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/exceptions.py +27 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/models.py +1819 -169
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/access.py +204 -17
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/admin.py +10 -2
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/core.py +145 -28
- cortexdbai-0.14.0/cortexdb/v1/ops/derivation.py +1336 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/rest.py +158 -28
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/records.py +1 -1
- cortexdbai-0.14.0/cortexdb/workers/__init__.py +29 -0
- cortexdbai-0.14.0/cortexdb/workers/derivation.py +800 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/pyproject.toml +14 -1
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/scripts/error_codes.json +244 -27
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/scripts/generate_models.py +28 -0
- cortexdbai-0.14.0/tests/_memory_tool_calls.py +48 -0
- cortexdbai-0.14.0/tests/live/test_live_derivation_worker.py +94 -0
- cortexdbai-0.14.0/tests/live/test_live_memory_tool.py +72 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/live/test_live_shared_memory.py +318 -4
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_access_api.py +106 -0
- cortexdbai-0.14.0/tests/test_client_parity.py +226 -0
- cortexdbai-0.14.0/tests/test_corrections.py +265 -0
- cortexdbai-0.14.0/tests/test_derivation.py +247 -0
- cortexdbai-0.14.0/tests/test_derivation_governance.py +741 -0
- cortexdbai-0.14.0/tests/test_derivation_worker.py +469 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_errors_and_auth.py +23 -3
- cortexdbai-0.14.0/tests/test_feed_consumers_and_episodes.py +217 -0
- cortexdbai-0.14.0/tests/test_generated_models.py +26 -0
- cortexdbai-0.14.0/tests/test_memory_tool.py +345 -0
- cortexdbai-0.14.0/tests/test_policy_test.py +153 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_read_write_fields.py +22 -0
- cortexdbai-0.14.0/tests/test_rederive.py +118 -0
- cortexdbai-0.14.0/tests/test_review.py +163 -0
- cortexdbai-0.13.0/tests/test_client_parity.py +0 -129
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/LICENSE +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ag2/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ag2/agent.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ag2/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/agno/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/agno/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/agno/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/autogen/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/autogen/agent.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/autogen/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/beeai/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/beeai/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/beeai/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/camel/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/camel/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/camel/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/controlflow/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/controlflow/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/crewai/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/crewai/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/crewai/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/deepinfra/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/deepinfra/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/deepinfra/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/deepinfra/openai_compat.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dify/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dify/manifest.yaml +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dify/tool.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dspy/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dspy/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/dspy/retriever.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/fireworks/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/fireworks/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/fireworks/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/fireworks/openai_compat.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/flowise/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/flowise/node.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/google_adk/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/google_adk/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/groq/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/groq/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/groq/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/groq/openai_compat.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/hermes/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/hermes/provider.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/instructor/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/instructor/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langchain/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langchain/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langchain/retriever.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langchain/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langgraph/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/langgraph/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/letta/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/letta/storage.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/llamaindex/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/llamaindex/memory.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/nemo_guardrails/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/nemo_guardrails/actions.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/nemo_guardrails/knowledge_base.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ollama/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ollama/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/ollama/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/openai_agents/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/openai_agents/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/prefect/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/prefect/blocks.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/prefect/tasks.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/pydanticai/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/pydanticai/dependencies.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/pydanticai/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/smolagents/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/smolagents/tools.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/temporal/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/temporal/activities.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/temporal/interceptor.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/together/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/together/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/together/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/together/openai_compat.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/vllm/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/vllm/config.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/vllm/embeddings.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/integrations/vllm/openai_compat.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/py.typed +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/consistency.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/diagnostics.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/fragments.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/code.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/erasure.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/native.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/org.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/ops/scim.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/cortexdb/v1/source.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/scripts/generate_errors.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/_harness.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/conftest.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/live/__init__.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/live/conftest.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_admin_and_rest.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_admin_retention.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_answer_unavailable.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_code_namespace.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_conflicts.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_consistency.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_delete_blob.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_erasures_forget.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_integration_write_barriers.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_matched_fragments.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_org_routes.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_readme_examples.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_recall_hints_capabilities.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_scim.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_signup.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_source.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_streams.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_unknown_method_guidance.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_v093_surfaces.py +0 -0
- {cortexdbai-0.13.0 → cortexdbai-0.14.0}/tests/test_with_options.py +0 -0
|
@@ -15,6 +15,17 @@ server adds goes in this table in the same change.
|
|
|
15
15
|
`forget_routes*.rs`, `code_routes.rs`, `commitment_routes.rs`, `source_erasure_routes.rs` and the rest).
|
|
16
16
|
- **Base:** `origin/sharedcontext` at `4618df85`, the final 0.14.0 server, 206 paths and 237 operations (a path with
|
|
17
17
|
two methods is two rows). The field families are in the second table.
|
|
18
|
+
- **Since then (CortexDB 0.15.0, `cortexdbai` 0.14.0):** N10 step 0's `derivation_provenance_v1` adds one route,
|
|
19
|
+
`GET /v1/derivation/decisions`; `derivation_policy_v1` (M4) adds `GET /v1/derivation/policy`, `/templates`,
|
|
20
|
+
`/taxonomy`, `PUT`, `GET` and `DELETE /v1/derivation/settings`, `GET /v1/derivation/texts` and
|
|
21
|
+
`POST /v1/derivation/texts/erase`, and (M5) `POST /v1/derivation/policy/test`; `derivation_feed_v1` (M8) adds
|
|
22
|
+
`GET /v1/derivation/feed`; `corrections_v1` (M3) adds `POST` and `GET /v1/corrections`, `GET` and
|
|
23
|
+
`DELETE /v1/corrections/{id}` and `GET /v1/memory/about`; `derivation_review_v1` (M6) adds `GET /v1/review` and
|
|
24
|
+
`POST /v1/review/decisions`; `derivation_rederive_v1` (M7) adds `POST /v1/derivation/rederive`,
|
|
25
|
+
`GET /v1/derivation/rederive/{job_id}`, `POST .../cancel` and `GET /v1/derivation/report`; M8's records add
|
|
26
|
+
`GET /v1/derivation/feed/consumers` (`derivation_feed_v1`) and `POST /v1/episodes` and `DELETE /v1/episodes/{id}`
|
|
27
|
+
(`declared_episodes_v1`); and they, `derived_by_v1` (M0.6) and the importers' modes (M13) add the field families
|
|
28
|
+
at the end of the second table: 226 paths and 262 operations.
|
|
18
29
|
- **The method column** is read from the SDK itself: each method's docstring names its route first.
|
|
19
30
|
- **Status:** `covered` (both clients), or `not covered` with the reason.
|
|
20
31
|
|
|
@@ -23,7 +34,7 @@ server adds goes in this table in the same change.
|
|
|
23
34
|
- **Unit** (`tests/`, run by CI's `pytest -q` in `sdks/python`): every method on both clients sends the same
|
|
24
35
|
request (`test_client_parity.py`), and each route family's tests pin its requests and its answers' handling.
|
|
25
36
|
- **Live** (`tests/live/`, against a release binary of the merged tree, `CORTEXDB_BINARY=… pytest tests/live`): one
|
|
26
|
-
org's life in
|
|
37
|
+
org's life in 30 legs, run once on each client. The last leg calls every route the others do not, and checks that
|
|
27
38
|
each answers by its contract on a default server: 2xx, or the documented refusal of a switch the server leaves off
|
|
28
39
|
(`CODE_PLANE_DISABLED`, `COHORT_DISABLED`, `ICE_OFF`, plans' 404, the native memory host's routes, which a
|
|
29
40
|
plain server does not mount). With `CORTEXDB_LIVE_ROUTES=<file>` the run records every request it sent: on 0.14.0
|
|
@@ -46,7 +57,7 @@ These are served by the binary but are not the v1 API a client calls:
|
|
|
46
57
|
|
|
47
58
|
## Summary
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
258 operations: 256 covered by both clients, 2 not covered (each row says why).
|
|
50
61
|
|
|
51
62
|
Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of them only partly (38 had no
|
|
52
63
|
`AsyncV1Client` method), and none of the shared-memory routes.
|
|
@@ -145,7 +156,7 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
145
156
|
| `POST /v1/answer` | Read | `answer`, `answer_stream` | covered |
|
|
146
157
|
| `GET /v1/apps/{id}` | Applications | `app_get` | covered |
|
|
147
158
|
| `PUT /v1/apps/{id}` | Applications | `app_put` | covered |
|
|
148
|
-
| `GET /v1/audit` | Audit | `audit_list` | covered |
|
|
159
|
+
| `GET /v1/audit` | Audit | `audit_list` (`action=`, CortexDB 0.15.0) | covered |
|
|
149
160
|
| `GET /v1/audit/chain` | Audit | `audit_chain` | covered |
|
|
150
161
|
| `POST /v1/audit/chain/verify` | Audit | `audit_chain_verify` | covered |
|
|
151
162
|
| `POST /v1/audit/verify` | Audit | `audit_verify` | covered |
|
|
@@ -202,13 +213,35 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
202
213
|
| `GET /v1/concepts/{id}/related` | Layers | `concept_related` | covered |
|
|
203
214
|
| `GET /v1/conflicts` | Layers | `list_conflicts` | covered |
|
|
204
215
|
| `GET /v1/conflicts/{id}` | Layers | `get_conflict` | covered |
|
|
205
|
-
| `POST /v1/conflicts/{id}/resolve` | Layers | `resolve_conflict` | covered |
|
|
206
|
-
| `GET /v1/
|
|
216
|
+
| `POST /v1/conflicts/{id}/resolve` | Layers | `resolve_conflict` (`loser=` and the answer's `correction_ids`, `corrections_v1`) | covered |
|
|
217
|
+
| `GET /v1/corrections` | Corrections (`corrections_v1`, CortexDB 0.15.0) | `corrections` (pages with `pages()`) | covered |
|
|
218
|
+
| `POST /v1/corrections` | Corrections (`corrections_v1`) | `correct`; its shorthands `reject`, `replace`, `pin`, `confirm` | covered |
|
|
219
|
+
| `DELETE /v1/corrections/{id}` | Corrections (`corrections_v1`) | `undo_correction` | covered |
|
|
220
|
+
| `GET /v1/corrections/{id}` | Corrections (`corrections_v1`) | `correction` | covered |
|
|
221
|
+
| `GET /v1/derivation/decisions` | Layers (`derivation_provenance_v1`, CortexDB 0.15.0) | `derivation_decisions` | covered |
|
|
222
|
+
| `GET /v1/derivation/feed` | Derivation (`derivation_feed_v1`, CortexDB 0.15.0) | `derivation_feed`; `feed_iter` follows its cursor; `cortexdb.workers.DerivationWorker` reads it | covered |
|
|
223
|
+
| `GET /v1/derivation/feed/consumers` | Derivation (`derivation_feed_v1`, CortexDB 0.15.0) | `feed_consumers` (pages with `pages()`) | covered |
|
|
224
|
+
| `GET /v1/derivation/policy` | Derivation (`derivation_policy_v1`, CortexDB 0.15.0) | `derivation_policy` (`include_texts=True`) | covered |
|
|
225
|
+
| `POST /v1/derivation/policy/test` | Derivation (`derivation_policy_v1`) | `derivation_policy_test` (a draft `policy` or a staged `changeset`; `sample` the newest N, 50 by default, or named event ids; `max_cost_usd`, 1 by default; `compare_with_active`, on here; its HTTP timeout raised to cover the sample, and never sent twice) | covered |
|
|
226
|
+
| `POST /v1/derivation/rederive` | Derivation (`derivation_rederive_v1`, CortexDB 0.15.0) | `rederive` (`regate` or `reextract`, a dry run by default; `event_ids` or the unsynced rows; an apply's `estimate_id`, `cap_usd` and `job_id` key; a dry run's HTTP timeout raised to cover its sample) | covered |
|
|
227
|
+
| `GET /v1/derivation/rederive/{job_id}` | Derivation (`derivation_rederive_v1`) | `rederive_job`; `rederive_wait` polls it until the job closes | covered |
|
|
228
|
+
| `POST /v1/derivation/rederive/{job_id}/cancel` | Derivation (`derivation_rederive_v1`) | `rederive_cancel` | covered |
|
|
229
|
+
| `GET /v1/derivation/report` | Derivation (`derivation_rederive_v1`) | `derivation_report` (`since`, `until`; `csv=True` answers the CSV text) | covered |
|
|
230
|
+
| `DELETE /v1/derivation/settings` | Derivation (`derivation_policy_v1`) | `delete_derivation_settings` | covered |
|
|
231
|
+
| `GET /v1/derivation/settings` | Derivation (`derivation_policy_v1`) | `derivation_settings` | covered |
|
|
232
|
+
| `PUT /v1/derivation/settings` | Derivation (`derivation_policy_v1`) | `put_derivation_settings` (a whole-record replace; `settings_fields` reads a record back into its fields) | covered |
|
|
233
|
+
| `GET /v1/derivation/status` | Layers | `derivation_status` (the `extraction` block, `at_least`, and `derived_by`) | covered |
|
|
234
|
+
| `GET /v1/derivation/taxonomy` | Derivation (`derivation_policy_v1`) | `derivation_taxonomy` | covered |
|
|
235
|
+
| `GET /v1/derivation/templates` | Derivation (`derivation_policy_v1`) | `derivation_templates` | covered |
|
|
236
|
+
| `GET /v1/derivation/texts` | Derivation (`derivation_policy_v1`) | `derivation_texts` (pages with `pages()`) | covered |
|
|
237
|
+
| `POST /v1/derivation/texts/erase` | Derivation (`derivation_policy_v1`) | `erase_derivation_texts` | covered |
|
|
207
238
|
| `GET /v1/directory` | Directory | `directory_search` | covered |
|
|
208
239
|
| `DELETE /v1/directory/{id}` | Directory | `directory_delete` | covered |
|
|
209
240
|
| `GET /v1/directory/{id}` | Directory | `directory_get` | covered |
|
|
210
241
|
| `PUT /v1/directory/{id}` | Directory | `directory_put` | covered |
|
|
211
242
|
| `GET /v1/episodes` | Layers | `episodes` | covered |
|
|
243
|
+
| `POST /v1/episodes` | Layers (`declared_episodes_v1`, CortexDB 0.15.0) | `declare_episode` | covered |
|
|
244
|
+
| `DELETE /v1/episodes/{id}` | Layers (`declared_episodes_v1`) | `delete_episode` | covered |
|
|
212
245
|
| `POST /v1/episodes/build` | Layers | `build_episodes` | covered |
|
|
213
246
|
| `POST /v1/erasures` | Erasures | `erase` | covered |
|
|
214
247
|
| `POST /v1/erasures/person` | Erasures | `erase_person` | covered |
|
|
@@ -235,16 +268,17 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
235
268
|
| `GET /v1/health` | Service and policy | `health` | covered |
|
|
236
269
|
| `POST /v1/import` | Import and export | `import_data` | covered |
|
|
237
270
|
| `POST /v1/import/jsonl` | Import and export | `import_jsonl` | covered |
|
|
238
|
-
| `POST /v1/import/letta` | Import and export | `import_letta` | covered |
|
|
239
|
-
| `POST /v1/import/mem0` | Import and export | `import_mem0` | covered |
|
|
240
|
-
| `POST /v1/import/openai` | Import and export | `import_openai` | covered |
|
|
241
|
-
| `POST /v1/import/zep` | Import and export | `import_zep` | covered |
|
|
271
|
+
| `POST /v1/import/letta` | Import and export | `import_letta` (`mode=`, CortexDB 0.15.0) | covered |
|
|
272
|
+
| `POST /v1/import/mem0` | Import and export | `import_mem0` (`mode=`) | covered |
|
|
273
|
+
| `POST /v1/import/openai` | Import and export | `import_openai` (`mode=`) | covered |
|
|
274
|
+
| `POST /v1/import/zep` | Import and export | `import_zep` (`mode=`, `keep_triples` too) | covered |
|
|
242
275
|
| `GET /v1/import/{id}` | Import and export | `import_status` | covered |
|
|
243
276
|
| `GET /v1/lifecycle` | Lifecycle | `lifecycle_events` | covered |
|
|
244
277
|
| `GET /v1/lifecycle/event/{lce_id}` | Lifecycle | `lifecycle_event` | covered |
|
|
245
278
|
| `GET /v1/lifecycle/memory-event/{evt_id}` | Lifecycle | `lifecycle_memory_event` | covered |
|
|
246
279
|
| `POST /v1/lifecycle/memory-event/{evt_id}/cancel` | Lifecycle | `cancel_event` | covered |
|
|
247
280
|
| `GET /v1/lifecycle/stream` | Lifecycle | `lifecycle_stream` | covered |
|
|
281
|
+
| `GET /v1/memory/about` | Corrections (`corrections_v1`, CortexDB 0.15.0) | `memory_about` (`include=("corrections", "held")` by default, `MEMORY_ABOUT_DEFAULT_INCLUDE`; pages with `pages()`) | covered |
|
|
248
282
|
| `POST /v1/memory/commitments/commands` | Native memory host | `native.commitment_command` | covered |
|
|
249
283
|
| `POST /v1/memory/commitments/current` | Native memory host | `native.commitment_current` | covered |
|
|
250
284
|
| `POST /v1/memory/commitments/evidence` | Native memory host | `native.commitment_evidence` | covered |
|
|
@@ -262,6 +296,8 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
262
296
|
| `POST /v1/publish` | Publish | `publish` | covered |
|
|
263
297
|
| `GET /v1/ready` | Service and policy | `ready` | covered |
|
|
264
298
|
| `POST /v1/recall` | Read | `recall` | covered |
|
|
299
|
+
| `GET /v1/review` | Review (`derivation_review_v1`, CortexDB 0.15.0) | `review` (`topic=`, `rule=`, `descend=`, `state=`; pages with `pages()`) | covered |
|
|
300
|
+
| `POST /v1/review/decisions` | Review (`derivation_review_v1`) | `review_decide`; its shorthands `approve`, `reject_held` (one decision each) | covered |
|
|
265
301
|
| `POST /v1/recall/stream` | Read | `recall_stream` | covered |
|
|
266
302
|
| `GET /v1/rollups` | Rollups | `rollups` | covered |
|
|
267
303
|
| `GET /v1/rollups/totals` | Rollups | `rollup_totals` | covered |
|
|
@@ -293,7 +329,7 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
293
329
|
| `PATCH /v1/vocabularies/{name}` | Vocabularies and phrases | `update_vocabulary` | covered |
|
|
294
330
|
| `PUT /v1/vocabularies/{name}` | Vocabularies and phrases | `replace_vocabulary` | covered |
|
|
295
331
|
|
|
296
|
-
## Fields, headers and errors of 0.14.0
|
|
332
|
+
## Fields, headers and errors of 0.14.0 and 0.15.0
|
|
297
333
|
|
|
298
334
|
| Family | Where | SDK | Status |
|
|
299
335
|
|---|---|---|---|
|
|
@@ -313,6 +349,7 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
313
349
|
| `X-Cortex-Subject-Token` (`subject_token_shadow_v1`) | the trusted operator's requests | `with_options(subject_token=...)` | covered |
|
|
314
350
|
| Chain fields of a mint (`act`, `app`, `client`, `run`, `run_start`, `taint`; `mint_chain_v1`) and `tenant` | `POST /v1/auth/tokens` | `mint_token(...)`, `mint_agent_token`, `mint_app_token`; `check_mint` refuses locally what the server always refuses; `with_token` | covered |
|
|
315
351
|
| `purpose` (`read_purpose_v1`) | `/v1/recall`, `/v1/recall/stream`, `/v1/answer`, `/v1/compose`, `POST /v1/access/{check,explain}` | `purpose="..."` (`[a-z0-9_-]{1,64}`, a `ValueError` otherwise); a read refused for want of its purpose raises `PolicyDeniedError` with `reason == "purpose_required"` and `purpose` | covered |
|
|
352
|
+
| `session` (`derivation_use_rules_v1`, CortexDB 0.15.0) | `/v1/recall`, `/v1/recall/stream`, `/v1/answer`, `/v1/compose` | `session="..."` on `recall`, `recall_stream`, `answer`, `answer_stream` and `compose` of both clients (1 to 256 bytes with no control character, a `ValueError` otherwise): where a read-time use rule is in force, memory from other sessions or older than its window is withheld and `warnings` says `use_rule_withheld: <n> events from earlier sessions`; a read without it sends the request it sent before | covered |
|
|
316
353
|
| `?scope=` on the by-id reads (a scope that does not hold the row is 404) | `/v1/facts/{id}`, `/v1/beliefs/{why,history}`, `/v1/concepts/{id}[/history,/related]`, `/v1/understanding/{id}[/history,/related]`, `/v1/conflicts/{id}[/resolve]`, `/v1/lifecycle/event/{id}`, `/v1/admin/events/{id}/chunks`, `/v1/erasures/{id}[/receipt,/verify]` | `scope=` | covered |
|
|
317
354
|
| `include_vectors=true` | the layer listings and the fact and concept reads by id | `include_vectors=True` | covered |
|
|
318
355
|
| Paging: `cursor` / `next_cursor` / `has_more` (the events' `le1.` cursor newest first, the scope list, the layers) | `GET /v1/events`, `/v1/scopes/list`, `/v1/facts`, `/v1/beliefs`, `/v1/episodes`, `/v1/understanding`, `/v1/concepts` and the access listings | `cursor=`, `pages(method, ...)` | covered |
|
|
@@ -320,8 +357,28 @@ Before the 0.14.0 work (`cortexdbai` 0.12.0), 67 operations were reached, 49 of
|
|
|
320
357
|
| `idempotency_key` on a declared belief; `owner` on `POST /v1/scopes`; `scope` on a temporal phrase; `batch_id` on the lifecycle stream | those routes | `idempotency_key=`, `owner=`, `scope=`, `batch_id=` | covered |
|
|
321
358
|
| `events_under_legal_hold`, `derived_under_legal_hold`, and `matched` counting what a hold kept | `POST /v1/forget`, `/v1/forget/preview` | in the answer (documented on both methods) | covered |
|
|
322
359
|
| `in_band`, `in_band_parts` of a change set's preview; the operator key's in-band activation under `deny` (`BREAK_GLASS_REQUIRED` class `in_band`, `NOTICE_UNAVAILABLE`, `REGISTRY_STALE`) | `POST /v1/access/changes/{id}/preview`, `/activate` | `ChangeSetPreview` in `cortexdb.v1.models`; `client.break_glass(...).changeset_activate(...)` | covered |
|
|
360
|
+
| A change set's 202 while its evaluation runs (0.14.1; `Retry-After`, a preview's `{state: "previewing"}`) | `POST /v1/access/changes`, `/{id}/parts`, `/{id}/preview`, `/{id}/activate` | sent again after `Retry-After` for at most `wait` seconds (`CHANGESET_WAIT_SECONDS`), then `V1EvaluationPendingError`; `wait=0` returns `EvaluationPending` | covered |
|
|
361
|
+
| `operator_plane` of a tenant binding, its dry run's included (0.14.1) | `POST /v1/admin/access/tenant-binding` | `TenantBindingResponse` in `cortexdb.v1.models`; `admin_tenant_binding` | covered |
|
|
323
362
|
| `deployment_mode` (`tenant_access_settings_v1`) | `GET`, `PUT /v1/admin/access/tenant-settings`; the access report's `tenant_settings` | `TenantAccessSettings` in `cortexdb.v1.models` | covered |
|
|
324
363
|
| `resend` of a write status (`"no"` for a failed write, never re-sent; `"new_key"` gone) | `GET /v1/experience/status` | `write_status(...)`; `IndexingFailedError` says never to re-send | covered |
|
|
325
364
|
| An omitted `X-Cortex-Actor` (issuers-file `prefix`, `hash` and `directory` tokens; SCIM clients) | every route | `actor=None`, `with_options(actor=None)`; derived from a token's `sub` when no `actor` is given (none for a mapped subject) | covered |
|
|
326
365
|
| `view` left to the server (granular at an org tree's shared scope) | `/v1/recall`, `/v1/answer`, `/v1/compose` | `view=None` (the default) | covered |
|
|
327
|
-
|
|
|
366
|
+
| `include=derivation` (`derivation_provenance_v1`, CortexDB 0.15.0): each row's `derivation` (verdict, models, prompt and gate versions, policy, `derived_by`, `pinned`, `confirmed`, `unsynced`) | `GET /v1/facts`, `/v1/facts/{id}`, `/v1/facts/timeline`, `/v1/beliefs`, `/v1/beliefs/why` | `include=["derivation"]` (sent once, comma-joined); `DerivationDetails` in `cortexdb.v1.models`; `derivation_of(row)` (`None` from a server that ignores the parameter) | covered |
|
|
367
|
+
| The status route's `extraction` block (`derivation_provenance_v1`) | `GET /v1/derivation/status` | `ExtractionStatus` in `cortexdb.v1.models`; `derivation_status(scope, at_least=)` | covered |
|
|
368
|
+
| `directive_not_enforced:<name>` in a write's `warnings` (0.15.0: `consolidate_into`, `confidence_floor`, `ttl_for_belief_layer`, `embed`, `async`) | `POST /v1/experience`, each `/v1/experience/bulk` `results` item, an import's 202 and `GET /v1/import/{id}` | `unenforced_directives(answer)`, `DIRECTIVES_NOT_ENFORCED` (`cortexdb.v1.derivation`) | covered |
|
|
369
|
+
| `enrich_kept` warnings of a change set (0.15.0: a companion put that keeps the stored `enrich`) | a staging's 200 (`POST /v1/access/changes`, `/{id}/parts`), every preview page | `enrich_kept(answer)`, `EnrichKeptWarning` (`cortexdb.v1.derivation`); `ChangeSetStatusWarningsItem`, `ChangeSetPreviewWarningsItem` in `cortexdb.v1.models` | covered |
|
|
370
|
+
| Derive records (`derivation_policy_v1`, CortexDB 0.15.0): a record of kind `derive` at `<scope>/attrs:derive`, its texts inline, in a change set of derive records alone; the preview's `derivation` section (`records`, `effective`, `narrowing`, `texts`, `warnings`) | `POST /v1/access/changes`, `/{id}/parts`, `/{id}/preview`, `/{id}/activate` | `derive_record(scope, body)` (`cortexdb.v1`, also `client.derive_record`) for `changeset_part`; `DerivationPreview` in `cortexdb.v1.models` | covered |
|
|
371
|
+
| `derived_by` (`derived_by_v1`, CortexDB 0.15.0): a write-back's `{name, version}`, on a typed triple only, part of write identity | `POST /v1/experience`, each `/v1/experience/bulk` and `/v1/experiences` item, `POST /v1/beliefs` | `derived_by=` on `experience` and `create_belief` (a mapping or `"name@version"`, checked before sending), a bulk item's `"derived_by"`; `EnvelopeDerivedBy`, `DeclareBeliefRequestDerivedBy` in `cortexdb.v1.models` | covered |
|
|
372
|
+
| `?derived_by=` and the answer's `derived_by` reports (`derived_by_v1`) | `GET /v1/derivation/status` | `derivation_status(scope, derived_by=[...])` (at most 8 names, comma-joined); `DerivedByReport` in `cortexdb.v1.models` | covered |
|
|
373
|
+
| The feed's erasure items, which name events only by `event_id_hashes` (BLAKE3 of `cortexdb/feed/erased-id/v1` and the id's 16 bytes) | `GET /v1/derivation/feed` | `feed_erased_id_hash(event_id)`, `erased_matches(item, held_ids)` (`cortexdb.v1.derivation`; the `blake3` extra, else pure Python); `DerivationFeedItem` in `cortexdb.v1.models` | covered |
|
|
374
|
+
| A feed page's `consumer_recorded` (format 11: the consumer's mark recorded) | `GET /v1/derivation/feed` | the page's key; `consumer_recorded` on `FeedIterator` and `AsyncFeedIterator` (the last page's) | covered |
|
|
375
|
+
| An erasure's `feed_consumers` (format 11: the consumers whose marks passed an erased event, with the events' hashes) and `corrections` (the corrections it erased); the proof's `governed_records` check | `GET /v1/erasures/{id}/receipt`, `GET /v1/erasures/{id}/verify` | `feed_consumers_of(answer)`, `verify_check(proof, GOVERNED_RECORDS_CHECK)` (`cortexdb.v1.derivation`); `ErasureReceiptResponseReceiptFeedConsumersItem`, `ErasureVerifyResponseFeedConsumersItem` in `cortexdb.v1.models` | covered |
|
|
376
|
+
| The reference worker (design §13.6): reads the feed as its consumer, writes results back in bulk with `provenance`, `derived_by` and deterministic keys, purges on erasure items by hash, saves its cursor after its writes commit, backs off on 503 | `GET /v1/derivation/feed`, `POST /v1/experience/bulk`, `GET /v1/events/{id}` | `cortexdb.workers`: `DerivationWorker`, `FileCursor`, `MemoryCursor`, `Triple` | covered |
|
|
377
|
+
| A Claude memory-tool handler (design §13.7): Anthropic's memory tool (`memory_20250818`) on a scope, one event per file version labelled `memory_file:<path>` | `POST /v1/experience`, `GET /v1/events`, `POST /v1/forget`, `POST /v1/erasures` | `cortexdb.memory_tool`: `CortexMemoryTool` (the Anthropic SDK's `BetaAbstractMemoryTool`; the `anthropic` extra), `CortexMemoryFiles` (without it) | covered |
|
|
378
|
+
| An importer's `mode` (`raw`, `keep`; Zep's `keep_triples`) and a row's `id` (N10 M13, CortexDB 0.15.0); `derived_by_dropped:<name>` in an import job's `warnings` | `POST /v1/import/mem0`, `/zep`, `/letta`, `/openai`; an import's 202 and `GET /v1/import/{id}` | `mode=` on the four importers (checked before sending; a row's `id` passes through); `dropped_derived_by(job)`, `IMPORT_MODES`, `ZEP_IMPORT_MODES` (`cortexdb.v1.derivation`) | covered |
|
|
379
|
+
| `?action=` of the audit listing, and a handler row's `action` (`derivation_consent`, `derivation_text_erase`, `correction`, `correction_undo`) | `GET /v1/audit` | `audit_list(action=...)`; `AuditRow.action` in `cortexdb.v1.models` | covered |
|
|
380
|
+
| A correction's target (a `fact_id` or a `claim` `{subject, predicate, object, negated}`), `bind`, `value`, `valid`, `reason`, `subject_principal` and `idempotency_key` (a replay answers 200 with `replayed: true`) | `POST /v1/corrections` | `correct(scope, action, target, ...)` and its shorthands (a target is a fact id string or a claim mapping; what the route always refuses is a `ValueError` before sending); `CorrectionRequest`, `CorrectionCreated`, `Correction`, `CorrectionPage`, `CorrectionUndone`, `MemoryAbout` in `cortexdb.v1.models` | covered |
|
|
381
|
+
| `loser` (`closed`, `wrong`) beside a `pick`, and the answer's `correction_ids` (`corrections_v1`, format 11) | `POST /v1/conflicts/{id}/resolve` | `resolve_conflict(..., loser=)`; the answer passes through | covered |
|
|
382
|
+
| A review decision (`derivation_review_v1`, CortexDB 0.15.0): `held_id`, `decision` (`approve`, `reject`), a rejection's `bind` (`claim`, `subject_predicate`) and `reason`, at most 100 a request; each result's `fact_id`, `pending`, `correction_id`, or `error_code` (`NOT_FOUND`, `REVIEW_ITEM_DECIDED`, `PROVENANCE_ERASED`, a retriable storage code) | `POST /v1/review/decisions` | `review_decide(scope, decisions)`, `approve(scope, held_id)`, `reject_held(scope, held_id, bind="claim")` (what the route always refuses is a `ValueError` before sending; a refused decision is a result, not an exception); `ReviewDecisionsRequest`, `ReviewDecisionsResponse`, `ReviewPage` in `cortexdb.v1.models`; `DERIVATION_REVIEW_V1`, `REVIEW_DECISIONS`, `REVIEW_BINDS`, `MAX_REVIEW_DECISIONS` (`cortexdb.v1.derivation`) | covered |
|
|
383
|
+
| `include=held` and a held item (`kind: "held"`, `held_id`, `rule`, `lapse_at`; `counts.held`) | `GET /v1/memory/about` | `memory_about(scope, include=("corrections", "held"))`; `MEMORY_ABOUT_INCLUDES` (`cortexdb.v1.derivation`) | covered |
|
|
384
|
+
| Typed errors with `retriable` and `details` | every route | one class per code (`cortexdb.v1.errors`, 371 codes from `scripts/error_codes.json`, built from the error catalog, `docs/API_REFERENCE_V1.md` §16) under status-family classes; documented `details` keys as properties; `retry_after` | covered |
|