atmem 2.3.6__tar.gz → 2.3.7__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.
- {atmem-2.3.6/atmem.egg-info → atmem-2.3.7}/PKG-INFO +16 -5
- {atmem-2.3.6 → atmem-2.3.7}/README.md +12 -3
- {atmem-2.3.6 → atmem-2.3.7}/atmem/atflows_service.py +13 -14
- atmem-2.3.7/atmem/bun_runtime.py +240 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/cli.py +58 -2
- atmem-2.3.7/atmem/continuity/__init__.py +5 -0
- atmem-2.3.7/atmem/continuity/client.py +256 -0
- atmem-2.3.7/atmem/continuity/example.py +56 -0
- atmem-2.3.7/atmem/continuity/integrations.py +112 -0
- atmem-2.3.7/atmem/continuity/langgraph_example.py +88 -0
- atmem-2.3.7/atmem/continuity/service.py +408 -0
- atmem-2.3.7/atmem/continuity/tools.py +108 -0
- atmem-2.3.7/atmem/contracts/continuity-event-v1.json +28 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/assets/app.css +8 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/assets/app.html +6 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/assets/app.js +35 -2
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/atbot_service.py +3 -7
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/compat.py +1 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/state.py +4 -6
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/store.py +68 -28
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/verify.py +25 -1
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/web.py +38 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/dashboard_daemon.py +16 -8
- atmem-2.3.7/atmem/durability.py +23 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/crypto.py +8 -2
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/models.py +5 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/service.py +40 -1
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/store.py +52 -13
- {atmem-2.3.6 → atmem-2.3.7}/atmem/home/artifacts.py +2 -5
- {atmem-2.3.6 → atmem-2.3.7}/atmem/home/service.py +6 -13
- {atmem-2.3.6 → atmem-2.3.7}/atmem/identity/store.py +27 -12
- {atmem-2.3.6 → atmem-2.3.7}/atmem/mcp/server.py +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/atmem/openclaw_install.py +1 -1
- atmem-2.3.7/atmem/processes.py +86 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/lifecycle.py +5 -5
- {atmem-2.3.6 → atmem-2.3.7}/atmem/service/application.py +2 -0
- {atmem-2.3.6 → atmem-2.3.7/atmem.egg-info}/PKG-INFO +16 -5
- {atmem-2.3.6 → atmem-2.3.7}/atmem.egg-info/SOURCES.txt +25 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem.egg-info/requires.txt +3 -1
- {atmem-2.3.6 → atmem-2.3.7}/docs/benchmarks/memory-integrity.md +24 -23
- atmem-2.3.7/docs/continuity.md +248 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/current-status.md +8 -1
- {atmem-2.3.6 → atmem-2.3.7}/docs/http-api.md +49 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/release-roadmap.md +34 -4
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.6.md +9 -7
- atmem-2.3.7/docs/releases/v2.3.7.md +117 -0
- atmem-2.3.7/docs/releases/v2.3.7b1.md +130 -0
- atmem-2.3.7/docs/releases/v2.3.7b2.md +105 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/atbot.md +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/atflows.md +15 -3
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/cli.md +3 -3
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/getting-started.md +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/index.md +8 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/integrations.md +2 -2
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/manifest.json +13 -6
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/portfolio.md +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/releases.md +18 -2
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/troubleshooting.md +9 -1
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/README.md +2 -2
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/openclaw.plugin.json +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/package-lock.json +2 -2
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/package.json +2 -2
- atmem-2.3.7/integrations/openclaw/test/fixtures/hook-context/2026.9.6.json +409 -0
- atmem-2.3.7/integrations/openclaw/test/hook-context-parser.mjs +16 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/lib/hook-context-shape.mjs +10 -2
- {atmem-2.3.6 → atmem-2.3.7}/pyproject.toml +5 -2
- atmem-2.3.7/tests/test_bun_runtime.py +93 -0
- atmem-2.3.7/tests/test_continuity_http.py +120 -0
- atmem-2.3.7/tests/test_continuity_integration.py +134 -0
- atmem-2.3.7/tests/test_continuity_product.py +313 -0
- atmem-2.3.7/tests/test_continuity_tools.py +42 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_control_plane.py +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_control_verify.py +50 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_dashboard_daemon.py +11 -4
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_documentation.py +1 -1
- atmem-2.3.7/tests/test_durability.py +41 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_encryption.py +13 -1
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_evidence_protection.py +98 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_local_identity.py +28 -0
- atmem-2.3.7/tests/test_processes.py +42 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_release_metadata.py +4 -1
- atmem-2.3.7/tests/test_windows_atomic_startup.py +44 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_atflows_handoff.py +1 -1
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_installed_package.py +5 -2
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_upgrade_from_2_1.py +5 -4
- {atmem-2.3.6 → atmem-2.3.7}/LICENSE +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/MANIFEST.in +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/base.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/callbacks.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/crewai.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/evidence_profiles.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/google_adk.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/langgraph.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/microsoft_agent.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/openai_agents.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/pydantic_ai.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/adapters/smolagents.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/deterministic-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/mem0-head-to-head-2.3.3b1-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/mem0-oss-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/retrieval-calibration-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/retrieval-heldout-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/task-state-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/data/thresholds-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/external.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/profiles.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/retrieval.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/benchmark/runner.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/client.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/contracts/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/contracts/execution.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/contracts/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/contracts/task_state.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/contracts/versions.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/assets/atmem.jpg +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/atbot_companion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/blackbox.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/evidence.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/explain.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/hosts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/jev_service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/manager.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/openclaw_native.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/openclaw_topology.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/query_expansion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/server.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/topology.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/control/ui.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/canonical.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/fact_keys.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/keys.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/storage.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/core/time.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/canonical.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/client.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/config.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/transport.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/delegated/validation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/evidence/accounts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/coverage.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/events.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/projection.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/retention.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/execution/status.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/classify.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/context.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/review.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/rules.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/extract/validation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/identity.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/maintenance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/store.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/graph/traverse.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/home/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/home/layout.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/identity/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/identity/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/identity/service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/incidents/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/incidents/detect.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/integrations/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/integrations/atflows.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/export.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/importer.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/mem0.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/interchange/plan.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/attestation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/registry.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/report.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/invariants/verdict.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/investigate.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/invalidation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/maintenance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/lifecycle/service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/locking.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/maintenance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/mcp/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/access.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/index.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/invalidation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/processors.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/media/service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/memory.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/onboarding.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/onboarding_verify.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/langgraph.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/loading.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/mem0.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/pydantic_ai.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/runtime.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/server.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/signing.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/provider_adapters/worker.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/cache.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/calibration-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/calibration.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/fusion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/graph.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/graph_signal.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/hybrid.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/rank.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/signals.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/retrieve/support.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/admin-audit.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/benchmark-cases.schema.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/benchmark-report.schema.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/capabilities.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/context-package.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/graph-path.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/host-task-lifecycle-request.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/host-task-observation-request.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/host-task-proposal-request.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/invariant-registry.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/media-observation.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/memory-archive.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/memory-lifecycle.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/memory-proposal.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/onboarding-state.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/recall-request.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/retrieval-decision.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/scope.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/semantic-health.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/service-job.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/service-key.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/service-principal.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/source-capture.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-context-package.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-profile.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-session-binding.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-start-request.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-state-proposal.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-state.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/task-transition-decision.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/schemas/v1/unified-health.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/health.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/index.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/models.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/pgvector.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/providers.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/semantic/qdrant.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/admin_audit.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/auth.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/cache_policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/config.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/jobs.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/observability.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/recovery.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/server/repositories.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/service/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/service/executions.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/store/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/store/health.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/store/postgres.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/store/sqlite.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/binding.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/context.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/enablement.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/enforcement.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/governance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/guards.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/host_boundary.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/models.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/observability.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/profiles.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/provenance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/task_state/service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/telemetry/__init__.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem/telemetry/retrieval.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem.egg-info/dependency_links.txt +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem.egg-info/entry_points.txt +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/atmem.egg-info/top_level.txt +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/agent-blackbox.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/atbot-release.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/audit-log-spec.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/audit-search.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/auditing-guide.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/benchmarks.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/capabilities.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/context-provider-adapters.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1/inject.next-turn-same-nonce.valid.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1/inject.valid.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1/test-vectors.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1/trust.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1/withhold.valid.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-provider-v1.schema.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-context-request-v1.schema.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-request-auth-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/contracts/delegated-request-auth-v1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/control-plane.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/dashboard-design-language.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/data-storage-and-backup.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/delegated-context-provider.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/entity-relationship-memory.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/benchmark-deterministic-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/longmemeval-s-retrieval-12-v1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/longmemeval-s-support-ranking-2026-09-02.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/onboarding/http.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/onboarding/langgraph.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/onboarding/openclaw.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/examples/onboarding/pydantic-ai.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/framework-adapters.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/generic-adapter.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/governed-task-state.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/003/20260909T043658Z-740c5c89d63c-host-compatibility.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/003/20260909T052000Z-740c5c89d63c-mem0-latest-hosts.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/003/20260909T052000Z-740c5c89d63c-mem0-latest-hosts.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/003/20260909T055300Z-04a063ce1e7b-publication.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/003/20260910-storizon-published-2.2.6.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/020/20260909-progress-card-observations.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/020/20260909-selective-context-and-precise-time.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/020/20260912-m0-investigation-preview.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/020/20260912-release-candidate-correctness-hardening.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/021/20260912-m0-findings-ui.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/022/20260909-dashboard-usability.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/026/20260920T094307Z-85c2ae2-atflows-b2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/026/20260920T105859Z-atmem-234-stable.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/028/20260913-encrypted-evidence-access.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/029/2026-09-13-local-user-management.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/030/2026-09-13-portable-home.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/baseline.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/consistency-audit.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/core-hybrid-benchmark.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/core-hybrid-calibration.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/core-hybrid-review.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/graph-calibration-four-profile.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/graph-calibration.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/graph-nomination.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/matched-v2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/numpy-benchmark.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/numpy-review.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/profiling.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/031/release-2.3.3.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/implementation-evidence/README.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/integration-guide.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/invariants.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/memory-extraction.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/memory-interchange.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/multimodal-observations.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/onboarding.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/openclaw-setup.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/production-service.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/release-coordination.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v1.0.0.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.0.0.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.0.1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.1.0.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.0.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.3.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.4.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.5.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b10.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b11.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b3.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b4.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b5.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b8.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.2.6b9.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.0.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.0b1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.3.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.4.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.4b1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.4b2.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.5.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/releases/v2.3.6b1.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/retrieval-quality.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/saas-integration.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/security/production-threat-model.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/semantic-search.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/spec-kit.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/storage-performance.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/dashboard.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/evidence.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/examples.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/mcp.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/python.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website/reference.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/docs/website-contributing.md +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/index.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/delegated-identity.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/execution-spool.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/rpc-client.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/setup.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/task-tools.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/tool-errors.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/tool-observations.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/tool-result-comparison.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/src/types.ts +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/blackbox-diagnostics.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/dashboard-live.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/delegated-context-contract.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/delegated-identity.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/delegated-journey.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/execution-spool.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.7.1-2.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.8.1.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.9.2.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.9.3.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.9.4.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/fixtures/hook-context/2026.9.5.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/hook-context-compat.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/hooks.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/lib/record-hook-context.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/manifest.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/setup.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/smoke.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/task-journey.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/task-tools.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/tool-observations.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/test/tool-result-comparison.mjs +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/integrations/openclaw/tsconfig.json +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/setup.cfg +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_api_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_api_idempotency.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_api_upgrade.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_atbot_companion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_atbot_service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_atflows_review.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_auditability.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_benchmark_cli.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_benchmark_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_benchmark_external.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_benchmark_memory_integrity_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_benchmark_runner.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_blackbox.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_cli.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_cli_guidance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_contracts_v1.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_control_evidence.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_dashboard.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_delegated_context.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_delegated_control.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_delegated_transport.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_execution_capture.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_execution_identity.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_extract.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_extract_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_extract_proposals.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_extract_upgrade.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_feature_surfaces.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_forget_verification.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_framework_adapter_conformance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_framework_adapter_packaging.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_framework_adapters.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_framework_delegated_adapters.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_generic_control.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_graph.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_graph_aliases.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_graph_lifecycle.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_graph_quality.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_home.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_host_adapter.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_http_api.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_incident_resolution.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_interchange.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_jev_lab.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_jev_service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_langgraph_provider.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_layers.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_lifecycle.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_lifecycle_migration.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_locking.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_maintenance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_mcp.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_media_governance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_media_observations.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_media_packaging.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_mem0_provider.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_memory.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_onboarding.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_onboarding_recovery.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_onboarding_services.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_openclaw_compat.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_openclaw_control.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_openclaw_install.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_openclaw_topology.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_production_benchmarks.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_cli.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_integration.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_packaging.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_performance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_runtime.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_provider_server.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_pydantic_provider.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_recall_evidence.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_restore_receipt.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_adapter_conformance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_benchmark.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_cache.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_candidate_union.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_graph_fusion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_quality.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieval_signals_and_cache.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_retrieve.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_sdk_packaging.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_health.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_matrix_cache.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_parity.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_policy_invalidation.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_profiles.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_rebuild.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_schema.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_search.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_semantic_setup.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_spec_task_inventory.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_storage_packaging.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_store_transactions.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_supporting_evidence.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_adapters.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_atbot.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_benchmark.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_binding.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_cli.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_clock.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_context.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_dashboard.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_deletion.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_expiry.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_governance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_guards.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_host_boundary.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_host_contracts.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_observability.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_performance.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_policy.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_prerequisites.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_schemas.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_service.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_session_binding.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_store.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_tamper.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_upgrade.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_task_state_walking_skeleton.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tests/test_website_docs.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/benchmark_core_hybrid.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/benchmark_numpy_cache.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/benchmark_storage.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/check_invariants.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/check_spec_tasks.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/release_metadata.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/run_longmemeval_retrieval.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/run_mem0_openclaw_live.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_atflows_delegated.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_delegated_package.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_delegated_transport.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/smoke_mem0_roleplay.py +0 -0
- {atmem-2.3.6 → atmem-2.3.7}/tools/verify_audit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atmem
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.7
|
|
4
4
|
Summary: Host-neutral Agent Black Box and reversible memory control plane.
|
|
5
5
|
Author-email: Javad Taghia <taghia.javad@gmail.com>
|
|
6
6
|
Maintainer-email: Aetna / AtMem <aetna000@gmail.com>
|
|
@@ -25,11 +25,13 @@ Requires-Python: >=3.10
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: atmem-atbot==0.1.0
|
|
28
|
-
Requires-Dist: atflows==0.1.
|
|
28
|
+
Requires-Dist: atflows==0.1.3
|
|
29
29
|
Requires-Dist: cryptography<49,>=42
|
|
30
30
|
Provides-Extra: atflows
|
|
31
31
|
Provides-Extra: dev
|
|
32
32
|
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: certifi>=2024.2.2; extra == "dev"
|
|
34
|
+
Requires-Dist: loguru<1,>=0.7; extra == "dev"
|
|
33
35
|
Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "dev"
|
|
34
36
|
Provides-Extra: semantic
|
|
35
37
|
Requires-Dist: sentence-transformers<6.0.0,>=5.0.0; extra == "semantic"
|
|
@@ -79,12 +81,12 @@ Dynamic: license-file
|
|
|
79
81
|
|
|
80
82
|
# AtMem
|
|
81
83
|
|
|
82
|
-
[](./docs/releases/v2.3.7.md)
|
|
83
85
|
[](https://github.com/aetna000/atmem/actions/workflows/ci.yml)
|
|
84
86
|
|
|
85
87
|
**AtMem is a host-neutral Agent Black Box and reversible memory control plane.**
|
|
86
88
|
|
|
87
|
-
> **
|
|
89
|
+
> **AtMem 2.3.7:** Product-owned continuity helps connected workflows reuse completed results, reconcile supported destinations, and stop uncertain work safely. AtFlows 0.1.3 adds attempt visibility and grouped event charts. See the [release note](./docs/releases/v2.3.7.md), [setup guide](./docs/continuity.md), and [recorded evidence](./benchmarks/agent_continuity/reports/product-continuity-20260925.md). Previous benchmarks retain their tested-version provenance.
|
|
88
90
|
> It records exact host-observed text and supported multimodal boundaries by default,
|
|
89
91
|
> while keeping every claim limited to what the connected agent actually supplied.
|
|
90
92
|
|
|
@@ -114,6 +116,15 @@ always-present local vector index. Do **not** install AtBot separately. During
|
|
|
114
116
|
hosted provider, or the safe deterministic fallback. API keys stay in
|
|
115
117
|
environment variables; AtMem does not save them.
|
|
116
118
|
|
|
119
|
+
In 2.3.7, `pip install atmem` installs the Python packages only; pip does not
|
|
120
|
+
run a post-install downloader. On the first `atmem init`, if compatible Bun is not
|
|
121
|
+
already installed, AtMem clearly announces and downloads its pinned official
|
|
122
|
+
Bun runtime for AtFlows, verifies the archive against a release-pinned SHA-256,
|
|
123
|
+
and stores it under `~/.atmem/runtime/bun`. It does not require administrator
|
|
124
|
+
rights or change the global `PATH`. A compatible system Bun is reused instead.
|
|
125
|
+
AtFlows may then use network access once to prepare its separately packaged
|
|
126
|
+
web runtime. Ordinary AtMem memory operations do not require Bun or AtFlows.
|
|
127
|
+
|
|
117
128
|
### 2. Connect your agent
|
|
118
129
|
|
|
119
130
|
#### OpenClaw — fully managed
|
|
@@ -784,7 +795,7 @@ npm run smoke
|
|
|
784
795
|
The latest stable release is **2.3.6** with matching OpenClaw bridge source
|
|
785
796
|
**2.3.6**. Release validation requires exact Python/bridge alignment; AtBot
|
|
786
797
|
retains its independent stable compatible version **0.1.0** and AtFlows remains
|
|
787
|
-
**0.1.
|
|
798
|
+
**0.1.3**.
|
|
788
799
|
|
|
789
800
|
## License
|
|
790
801
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# AtMem
|
|
2
2
|
|
|
3
|
-
[](./docs/releases/v2.3.7.md)
|
|
4
4
|
[](https://github.com/aetna000/atmem/actions/workflows/ci.yml)
|
|
5
5
|
|
|
6
6
|
**AtMem is a host-neutral Agent Black Box and reversible memory control plane.**
|
|
7
7
|
|
|
8
|
-
> **
|
|
8
|
+
> **AtMem 2.3.7:** Product-owned continuity helps connected workflows reuse completed results, reconcile supported destinations, and stop uncertain work safely. AtFlows 0.1.3 adds attempt visibility and grouped event charts. See the [release note](./docs/releases/v2.3.7.md), [setup guide](./docs/continuity.md), and [recorded evidence](./benchmarks/agent_continuity/reports/product-continuity-20260925.md). Previous benchmarks retain their tested-version provenance.
|
|
9
9
|
> It records exact host-observed text and supported multimodal boundaries by default,
|
|
10
10
|
> while keeping every claim limited to what the connected agent actually supplied.
|
|
11
11
|
|
|
@@ -35,6 +35,15 @@ always-present local vector index. Do **not** install AtBot separately. During
|
|
|
35
35
|
hosted provider, or the safe deterministic fallback. API keys stay in
|
|
36
36
|
environment variables; AtMem does not save them.
|
|
37
37
|
|
|
38
|
+
In 2.3.7, `pip install atmem` installs the Python packages only; pip does not
|
|
39
|
+
run a post-install downloader. On the first `atmem init`, if compatible Bun is not
|
|
40
|
+
already installed, AtMem clearly announces and downloads its pinned official
|
|
41
|
+
Bun runtime for AtFlows, verifies the archive against a release-pinned SHA-256,
|
|
42
|
+
and stores it under `~/.atmem/runtime/bun`. It does not require administrator
|
|
43
|
+
rights or change the global `PATH`. A compatible system Bun is reused instead.
|
|
44
|
+
AtFlows may then use network access once to prepare its separately packaged
|
|
45
|
+
web runtime. Ordinary AtMem memory operations do not require Bun or AtFlows.
|
|
46
|
+
|
|
38
47
|
### 2. Connect your agent
|
|
39
48
|
|
|
40
49
|
#### OpenClaw — fully managed
|
|
@@ -705,7 +714,7 @@ npm run smoke
|
|
|
705
714
|
The latest stable release is **2.3.6** with matching OpenClaw bridge source
|
|
706
715
|
**2.3.6**. Release validation requires exact Python/bridge alignment; AtBot
|
|
707
716
|
retains its independent stable compatible version **0.1.0** and AtFlows remains
|
|
708
|
-
**0.1.
|
|
717
|
+
**0.1.3**.
|
|
709
718
|
|
|
710
719
|
## License
|
|
711
720
|
|
|
@@ -11,7 +11,6 @@ from importlib.metadata import PackageNotFoundError, version
|
|
|
11
11
|
import json
|
|
12
12
|
import os
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
import shutil
|
|
15
14
|
import signal
|
|
16
15
|
import subprocess
|
|
17
16
|
import sys
|
|
@@ -19,6 +18,7 @@ import time
|
|
|
19
18
|
from typing import Any
|
|
20
19
|
from urllib.parse import urlparse
|
|
21
20
|
|
|
21
|
+
from atmem.bun_runtime import ensure_bun, find_bun
|
|
22
22
|
from atmem.home.layout import compatible_home_path
|
|
23
23
|
|
|
24
24
|
|
|
@@ -54,9 +54,13 @@ def status() -> dict[str, Any]:
|
|
|
54
54
|
None,
|
|
55
55
|
) if record.get("instance_id") else None
|
|
56
56
|
selected = owned or (servers[0] if len(servers) == 1 else None)
|
|
57
|
+
bun = find_bun()
|
|
57
58
|
result: dict[str, Any] = {
|
|
58
59
|
"installed_version": installed_version,
|
|
59
|
-
"bun_available": bool(
|
|
60
|
+
"bun_available": bool(bun),
|
|
61
|
+
"bun_version": bun.get("version") if bun else None,
|
|
62
|
+
"bun_path": bun.get("path") if bun else None,
|
|
63
|
+
"bun_managed_by_atmem": bool(bun and bun.get("managed")),
|
|
60
64
|
"running": bool(servers),
|
|
61
65
|
"managed_by_atmem": bool(owned),
|
|
62
66
|
"pid": selected.get("pid") if selected else None,
|
|
@@ -88,7 +92,7 @@ def status() -> dict[str, Any]:
|
|
|
88
92
|
elif result["restart_required"]:
|
|
89
93
|
result["warning"] = "AtFlows is running an older version than the installed package."
|
|
90
94
|
elif installed_version and not result["running"] and not result["bun_available"]:
|
|
91
|
-
result["warning"] = "Bun 1.1+ is missing.
|
|
95
|
+
result["warning"] = "Bun 1.1+ is missing. Run `atmem init`; AtMem will download and verify its private Bun runtime automatically."
|
|
92
96
|
return result
|
|
93
97
|
|
|
94
98
|
|
|
@@ -147,16 +151,7 @@ def ensure_started(atmem_url: str, *, timeout: float = 60.0) -> dict[str, Any]:
|
|
|
147
151
|
current = status()
|
|
148
152
|
if current["running"]:
|
|
149
153
|
return current
|
|
150
|
-
bun =
|
|
151
|
-
if not bun:
|
|
152
|
-
raise RuntimeError("Bun is required to start AtFlows. Install Bun 1.1+ from https://bun.sh, then run `atmem init` again.")
|
|
153
|
-
try:
|
|
154
|
-
bun_version = subprocess.run([bun, "--version"], capture_output=True, text=True, timeout=5, check=False)
|
|
155
|
-
pieces = [int(part) for part in bun_version.stdout.strip().split(".")[:2]]
|
|
156
|
-
if bun_version.returncode != 0 or pieces < [1, 1]:
|
|
157
|
-
raise ValueError("Bun 1.1+ is required")
|
|
158
|
-
except (OSError, ValueError, subprocess.TimeoutExpired):
|
|
159
|
-
raise RuntimeError("Bun 1.1+ is required to start AtFlows; upgrade Bun, then run `atmem init` again.") from None
|
|
154
|
+
bun = ensure_bun()
|
|
160
155
|
from atmem.cli import _atflows_executable
|
|
161
156
|
|
|
162
157
|
executable = _atflows_executable(current["installed_version"])
|
|
@@ -169,6 +164,7 @@ def ensure_started(atmem_url: str, *, timeout: float = 60.0) -> dict[str, Any]:
|
|
|
169
164
|
log_path.chmod(0o600)
|
|
170
165
|
previous_ids = {row.get("instance_id") for row in _running()}
|
|
171
166
|
environment = os.environ.copy()
|
|
167
|
+
environment["PATH"] = str(Path(bun["path"]).parent) + os.pathsep + environment.get("PATH", "")
|
|
172
168
|
environment["ATFLOWS_ATMEM_AUTH_URL"] = atmem_url.rstrip("/")
|
|
173
169
|
environment["DASHBOARD_HOST"] = "127.0.0.1"
|
|
174
170
|
environment["PROXY_HOST"] = "127.0.0.1"
|
|
@@ -206,7 +202,10 @@ def ensure_started(atmem_url: str, *, timeout: float = 60.0) -> dict[str, Any]:
|
|
|
206
202
|
time.sleep(0.25)
|
|
207
203
|
if process.poll() is None:
|
|
208
204
|
# Only terminate the process group started above, never another server.
|
|
209
|
-
os.
|
|
205
|
+
if os.name == "nt":
|
|
206
|
+
process.terminate()
|
|
207
|
+
else:
|
|
208
|
+
os.killpg(process.pid, signal.SIGTERM)
|
|
210
209
|
raise RuntimeError(
|
|
211
210
|
"AtFlows did not become ready. Check Bun >=1.1, network access for its first runtime preparation, "
|
|
212
211
|
f"and the private startup log at {log_path}. Run `atmem init` to retry."
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""Provision the pinned Bun runtime used by AtMem-managed AtFlows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from hashlib import sha256
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import platform
|
|
10
|
+
import shutil
|
|
11
|
+
import stat
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
import tempfile
|
|
15
|
+
from typing import Any
|
|
16
|
+
from urllib.request import Request, urlopen
|
|
17
|
+
from zipfile import BadZipFile, ZipFile
|
|
18
|
+
|
|
19
|
+
from atmem.home.layout import HomeLayout
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
BUN_VERSION = "1.4.2"
|
|
23
|
+
_MAX_ARCHIVE_BYTES = 200 * 1024 * 1024
|
|
24
|
+
_ASSETS: dict[tuple[str, str], tuple[str, str]] = {
|
|
25
|
+
("darwin", "arm64"): (
|
|
26
|
+
"bun-darwin-aarch64.zip",
|
|
27
|
+
"90987a3a16d7db556d886ac3d551e7b6d3edf0a1cf43acaed622e8676be1d12f",
|
|
28
|
+
),
|
|
29
|
+
("darwin", "x64"): (
|
|
30
|
+
"bun-darwin-x64.zip",
|
|
31
|
+
"80520d7e17526308c9185d261679ac6d27798d3803a0e9f7ff9121ab8affb012",
|
|
32
|
+
),
|
|
33
|
+
("linux", "arm64"): (
|
|
34
|
+
"bun-linux-aarch64.zip",
|
|
35
|
+
"54328bbc2d9c8e0c9f892c544d66c57a83b84139e34909e5ee81758f1ac8fda7",
|
|
36
|
+
),
|
|
37
|
+
("linux", "x64"): (
|
|
38
|
+
"bun-linux-x64.zip",
|
|
39
|
+
"36368faef7527875d5ffa52e53cd48021741f2a83eb6208a8dd64068d422a913",
|
|
40
|
+
),
|
|
41
|
+
("windows", "arm64"): (
|
|
42
|
+
"bun-windows-aarch64.zip",
|
|
43
|
+
"a7a16b876a305fd1029c66dbd27007b4f6112ae896532f675878731a21e50cfd",
|
|
44
|
+
),
|
|
45
|
+
("windows", "x64"): (
|
|
46
|
+
"bun-windows-x64.zip",
|
|
47
|
+
"ce4c17497b2f29712a99d3d53f028de28cd42e3bacb8589599e7f000e49b6405",
|
|
48
|
+
),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def find_bun() -> dict[str, Any] | None:
|
|
53
|
+
"""Return a compatible system or AtMem-managed Bun without networking."""
|
|
54
|
+
|
|
55
|
+
system = shutil.which("bun")
|
|
56
|
+
if system:
|
|
57
|
+
detected = _inspect(Path(system), managed=False)
|
|
58
|
+
if detected:
|
|
59
|
+
return detected
|
|
60
|
+
target = _managed_executable()
|
|
61
|
+
inspected = _inspect(target, managed=True) if target.is_file() else None
|
|
62
|
+
if not inspected:
|
|
63
|
+
return None
|
|
64
|
+
try:
|
|
65
|
+
metadata = json.loads(target.with_name("install.json").read_text(encoding="utf-8"))
|
|
66
|
+
except (OSError, ValueError):
|
|
67
|
+
return None
|
|
68
|
+
if (
|
|
69
|
+
not isinstance(metadata, dict)
|
|
70
|
+
or metadata.get("format") != "atmem-managed-bun-v1"
|
|
71
|
+
or metadata.get("version") != inspected["version"]
|
|
72
|
+
or metadata.get("executable_sha256") != _file_digest(target)
|
|
73
|
+
):
|
|
74
|
+
return None
|
|
75
|
+
return inspected
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def ensure_bun() -> dict[str, Any]:
|
|
79
|
+
"""Return compatible Bun, provisioning the pinned runtime when necessary."""
|
|
80
|
+
|
|
81
|
+
existing = find_bun()
|
|
82
|
+
if existing:
|
|
83
|
+
return existing
|
|
84
|
+
asset, expected_digest = _asset()
|
|
85
|
+
target = _managed_executable()
|
|
86
|
+
target.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
87
|
+
url = (
|
|
88
|
+
f"https://github.com/oven-sh/bun/releases/download/"
|
|
89
|
+
f"bun-v{BUN_VERSION}/{asset}"
|
|
90
|
+
)
|
|
91
|
+
print(
|
|
92
|
+
f"Bun 1.1+ was not found. AtMem init is downloading official Bun "
|
|
93
|
+
f"{BUN_VERSION} for AtFlows.\n"
|
|
94
|
+
f" Source: {url}\n"
|
|
95
|
+
f" Destination: {target}\n"
|
|
96
|
+
" Security: the download must match AtMem's pinned SHA-256 before use.",
|
|
97
|
+
file=sys.stderr,
|
|
98
|
+
flush=True,
|
|
99
|
+
)
|
|
100
|
+
archive = _download(url, target.parent)
|
|
101
|
+
try:
|
|
102
|
+
actual_digest = _file_digest(archive)
|
|
103
|
+
if actual_digest != expected_digest:
|
|
104
|
+
raise RuntimeError(
|
|
105
|
+
"Bun download failed SHA-256 verification; the archive was not installed"
|
|
106
|
+
)
|
|
107
|
+
_extract_executable(archive, target)
|
|
108
|
+
finally:
|
|
109
|
+
archive.unlink(missing_ok=True)
|
|
110
|
+
inspected = _inspect(target, managed=True)
|
|
111
|
+
if not inspected or inspected["version"] != BUN_VERSION:
|
|
112
|
+
target.unlink(missing_ok=True)
|
|
113
|
+
raise RuntimeError(
|
|
114
|
+
f"AtMem provisioned Bun but could not verify version {BUN_VERSION}"
|
|
115
|
+
)
|
|
116
|
+
metadata = {
|
|
117
|
+
"format": "atmem-managed-bun-v1",
|
|
118
|
+
"version": BUN_VERSION,
|
|
119
|
+
"source": url,
|
|
120
|
+
"sha256": expected_digest,
|
|
121
|
+
"executable_sha256": _file_digest(target),
|
|
122
|
+
"executable": str(target),
|
|
123
|
+
}
|
|
124
|
+
target.with_name("install.json").write_text(
|
|
125
|
+
json.dumps(metadata, indent=2, sort_keys=True) + "\n", encoding="utf-8"
|
|
126
|
+
)
|
|
127
|
+
print(
|
|
128
|
+
f"Verified Bun {BUN_VERSION}. AtMem will use this private runtime for AtFlows; "
|
|
129
|
+
"your global PATH was not changed.",
|
|
130
|
+
file=sys.stderr,
|
|
131
|
+
flush=True,
|
|
132
|
+
)
|
|
133
|
+
return inspected
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _managed_executable() -> Path:
|
|
137
|
+
name = "bun.exe" if os.name == "nt" else "bun"
|
|
138
|
+
return HomeLayout.selected().runtime / "bun" / BUN_VERSION / "bin" / name
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _asset() -> tuple[str, str]:
|
|
142
|
+
system = platform.system().lower()
|
|
143
|
+
machine = platform.machine().lower()
|
|
144
|
+
architecture = (
|
|
145
|
+
"x64" if machine in {"amd64", "x86_64"}
|
|
146
|
+
else "arm64" if machine in {"arm64", "aarch64"}
|
|
147
|
+
else machine
|
|
148
|
+
)
|
|
149
|
+
try:
|
|
150
|
+
return _ASSETS[(system, architecture)]
|
|
151
|
+
except KeyError as exc:
|
|
152
|
+
raise RuntimeError(
|
|
153
|
+
f"AtMem cannot automatically provision Bun on {system}/{architecture}; "
|
|
154
|
+
"install Bun 1.1+ from https://bun.sh/docs/installation and rerun `atmem init`"
|
|
155
|
+
) from exc
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _inspect(executable: Path, *, managed: bool) -> dict[str, Any] | None:
|
|
159
|
+
try:
|
|
160
|
+
result = subprocess.run(
|
|
161
|
+
[str(executable), "--version"],
|
|
162
|
+
capture_output=True,
|
|
163
|
+
text=True,
|
|
164
|
+
timeout=10,
|
|
165
|
+
check=False,
|
|
166
|
+
)
|
|
167
|
+
version = result.stdout.strip()
|
|
168
|
+
pieces = tuple(int(part) for part in version.split(".")[:2])
|
|
169
|
+
except (OSError, ValueError, subprocess.TimeoutExpired):
|
|
170
|
+
return None
|
|
171
|
+
if result.returncode != 0 or pieces < (1, 1):
|
|
172
|
+
return None
|
|
173
|
+
return {
|
|
174
|
+
"path": str(executable.resolve(strict=False)),
|
|
175
|
+
"version": version,
|
|
176
|
+
"managed": managed,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _download(url: str, directory: Path) -> Path:
|
|
181
|
+
descriptor, name = tempfile.mkstemp(prefix=".bun-", suffix=".zip", dir=directory)
|
|
182
|
+
path = Path(name)
|
|
183
|
+
total = 0
|
|
184
|
+
try:
|
|
185
|
+
request = Request(url, headers={"User-Agent": "AtMem-Bun-Provisioner/1"})
|
|
186
|
+
with os.fdopen(descriptor, "wb") as output, urlopen(request, timeout=120) as response:
|
|
187
|
+
while True:
|
|
188
|
+
chunk = response.read(1024 * 1024)
|
|
189
|
+
if not chunk:
|
|
190
|
+
break
|
|
191
|
+
total += len(chunk)
|
|
192
|
+
if total > _MAX_ARCHIVE_BYTES:
|
|
193
|
+
raise RuntimeError("Bun download exceeded the 200 MiB safety limit")
|
|
194
|
+
output.write(chunk)
|
|
195
|
+
output.flush()
|
|
196
|
+
os.fsync(output.fileno())
|
|
197
|
+
return path
|
|
198
|
+
except Exception:
|
|
199
|
+
try:
|
|
200
|
+
os.close(descriptor)
|
|
201
|
+
except OSError:
|
|
202
|
+
pass
|
|
203
|
+
path.unlink(missing_ok=True)
|
|
204
|
+
raise
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _file_digest(path: Path) -> str:
|
|
208
|
+
digest = sha256()
|
|
209
|
+
with path.open("rb") as source:
|
|
210
|
+
for chunk in iter(lambda: source.read(1024 * 1024), b""):
|
|
211
|
+
digest.update(chunk)
|
|
212
|
+
return digest.hexdigest()
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _extract_executable(archive: Path, target: Path) -> None:
|
|
216
|
+
temporary = target.with_name(f".{target.name}.tmp")
|
|
217
|
+
temporary.unlink(missing_ok=True)
|
|
218
|
+
try:
|
|
219
|
+
with ZipFile(archive) as bundle:
|
|
220
|
+
name = "bun.exe" if os.name == "nt" else "bun"
|
|
221
|
+
members = [
|
|
222
|
+
item for item in bundle.infolist()
|
|
223
|
+
if not item.is_dir() and Path(item.filename).name == name
|
|
224
|
+
]
|
|
225
|
+
if len(members) != 1:
|
|
226
|
+
raise RuntimeError("official Bun archive did not contain exactly one executable")
|
|
227
|
+
member = members[0]
|
|
228
|
+
mode = (member.external_attr >> 16) & 0o170000
|
|
229
|
+
if mode == stat.S_IFLNK or member.file_size > _MAX_ARCHIVE_BYTES:
|
|
230
|
+
raise RuntimeError("official Bun archive contained an unsafe executable entry")
|
|
231
|
+
with bundle.open(member) as source, temporary.open("xb") as output:
|
|
232
|
+
shutil.copyfileobj(source, output, length=1024 * 1024)
|
|
233
|
+
output.flush()
|
|
234
|
+
os.fsync(output.fileno())
|
|
235
|
+
temporary.chmod(0o700)
|
|
236
|
+
os.replace(temporary, target)
|
|
237
|
+
except (BadZipFile, OSError) as exc:
|
|
238
|
+
raise RuntimeError(f"could not extract the verified Bun archive: {exc}") from exc
|
|
239
|
+
finally:
|
|
240
|
+
temporary.unlink(missing_ok=True)
|
|
@@ -83,6 +83,11 @@ def _atflows_executable(expected_version: str) -> Path | None:
|
|
|
83
83
|
paths = [
|
|
84
84
|
Path(sys.executable).with_name(name),
|
|
85
85
|
Path(sysconfig.get_path("scripts")) / name,
|
|
86
|
+
Path(
|
|
87
|
+
sysconfig.get_path(
|
|
88
|
+
"scripts", scheme="nt_user" if os.name == "nt" else "posix_user"
|
|
89
|
+
)
|
|
90
|
+
) / name,
|
|
86
91
|
Path(site.getuserbase()) / ("Scripts" if os.name == "nt" else "bin") / name,
|
|
87
92
|
]
|
|
88
93
|
found = shutil.which("atflows")
|
|
@@ -232,6 +237,11 @@ def _run_install_status(args: argparse.Namespace) -> None:
|
|
|
232
237
|
for label, package in (("AtMem", "atmem"), ("AtBot", "atmem-atbot"), ("AtFlows", "atflows")):
|
|
233
238
|
print(f" {label:<18}{report['packages'][package]}")
|
|
234
239
|
print(f" {'AtMem Home':<18}{report['home']}")
|
|
240
|
+
if flows.get("bun_available"):
|
|
241
|
+
ownership = "AtMem-managed" if flows.get("bun_managed_by_atmem") else "system"
|
|
242
|
+
print(f" {'Bun runtime':<18}{flows.get('bun_version')} ({ownership}: {flows.get('bun_path')})")
|
|
243
|
+
else:
|
|
244
|
+
print(f" {'Bun runtime':<18}not installed; `atmem init` downloads and SHA-256-verifies AtMem's private copy")
|
|
235
245
|
if shell_python and not launcher["same_python_as_shell"]:
|
|
236
246
|
print(f" ACTION `atmem` uses {sys.executable}, but `python` uses {shell_python}. Upgrade through the intended Python environment or remove a stale launcher from PATH.")
|
|
237
247
|
print("\nIntelligence")
|
|
@@ -1555,6 +1565,20 @@ or input errors.""",
|
|
|
1555
1565
|
"--envelope", required=True, help="JSON object file, or - for stdin"
|
|
1556
1566
|
)
|
|
1557
1567
|
|
|
1568
|
+
continuity_parser = subparsers.add_parser("continuity", help="Save work and inspect safe recovery")
|
|
1569
|
+
continuity_parser.add_argument("action", choices=("credential", "create", "list", "show", "enable", "disable", "abandon"))
|
|
1570
|
+
continuity_parser.add_argument("workflow", nargs="?")
|
|
1571
|
+
continuity_parser.add_argument("--file", help="JSON workflow definition for create")
|
|
1572
|
+
continuity_parser.add_argument("--operation")
|
|
1573
|
+
continuity_parser.add_argument("--reason")
|
|
1574
|
+
continuity_parser.add_argument("--url", default="http://127.0.0.1:8768")
|
|
1575
|
+
continuity_parser.add_argument("--token-env", default="ATMEM_EVIDENCE_TOKEN")
|
|
1576
|
+
continuity_parser.add_argument("--principal", help="Unique credential name for credential creation")
|
|
1577
|
+
continuity_parser.add_argument("--username", default="administrator")
|
|
1578
|
+
continuity_parser.add_argument("--coordinator", action="store_true", help="Create a narrow dynamic-tool coordinator credential")
|
|
1579
|
+
continuity_parser.add_argument("--workspace", help="Required fixed workspace for a coordinator credential")
|
|
1580
|
+
continuity_parser.add_argument("--token-only", action="store_true", help="Print only the new secret, suitable for assigning an environment variable")
|
|
1581
|
+
|
|
1558
1582
|
evidence_parser = subparsers.add_parser(
|
|
1559
1583
|
"evidence", help="Inspect the encrypted evidence vault with an explicit privilege"
|
|
1560
1584
|
)
|
|
@@ -1586,7 +1610,7 @@ or input errors.""",
|
|
|
1586
1610
|
command_parser.add_argument("query")
|
|
1587
1611
|
if name == "grant":
|
|
1588
1612
|
command_parser.add_argument("principal_id")
|
|
1589
|
-
command_parser.add_argument("role", choices=("viewer", "investigator", "evidence_collector"))
|
|
1613
|
+
command_parser.add_argument("role", choices=("viewer", "investigator", "evidence_collector", "continuity_host", "continuity_coordinator"))
|
|
1590
1614
|
command_parser.add_argument("--run-id")
|
|
1591
1615
|
if name == "revoke":
|
|
1592
1616
|
command_parser.add_argument("principal_id")
|
|
@@ -1729,6 +1753,34 @@ or input errors.""",
|
|
|
1729
1753
|
_run_blackbox(args)
|
|
1730
1754
|
return
|
|
1731
1755
|
|
|
1756
|
+
if args.command == "continuity":
|
|
1757
|
+
from atmem.continuity.client import ContinuityClient
|
|
1758
|
+
if args.action == "credential":
|
|
1759
|
+
from atmem.continuity.client import operator_credential
|
|
1760
|
+
if not args.principal:
|
|
1761
|
+
raise ValueError("credential requires --principal; provide a workflow ID to restrict a worker credential")
|
|
1762
|
+
if args.coordinator and (not args.workspace or args.workflow):
|
|
1763
|
+
raise ValueError("coordinator requires --workspace and no workflow ID")
|
|
1764
|
+
credential = operator_credential(args.url, args.username, getpass.getpass("AtMem password: "), args.principal,
|
|
1765
|
+
workflow_id=args.workflow, coordinator=args.coordinator, workspace_id=args.workspace)
|
|
1766
|
+
print(credential["token"]) if args.token_only else _print(credential)
|
|
1767
|
+
return
|
|
1768
|
+
client = ContinuityClient(args.url, os.environ.get(args.token_env, ""))
|
|
1769
|
+
if args.action == "create":
|
|
1770
|
+
if not args.file or not args.workflow:
|
|
1771
|
+
raise ValueError("create requires a workflow key and --file definition.json")
|
|
1772
|
+
value = client.create(args.workflow, json.loads(Path(args.file).read_text())["operations"])
|
|
1773
|
+
elif args.action == "list":
|
|
1774
|
+
value = client.request("GET", "/v1/continuity")
|
|
1775
|
+
elif args.action == "show":
|
|
1776
|
+
value = client.get(args.workflow)
|
|
1777
|
+
elif args.action in {"enable", "disable"}:
|
|
1778
|
+
value = client.configure(args.workflow, args.action == "enable")
|
|
1779
|
+
else:
|
|
1780
|
+
value = client.request("POST", f"/v1/continuity/{args.workflow}/abandon", {"name": args.operation, "reason": args.reason})
|
|
1781
|
+
_print(value)
|
|
1782
|
+
return
|
|
1783
|
+
|
|
1732
1784
|
if args.command == "evidence":
|
|
1733
1785
|
if args.evidence_command is None:
|
|
1734
1786
|
evidence_parser.print_help()
|
|
@@ -4528,7 +4580,11 @@ def _serve_dashboard(
|
|
|
4528
4580
|
|
|
4529
4581
|
atbot_manager = AtBotServiceManager()
|
|
4530
4582
|
companion_status = atbot_manager.status()
|
|
4531
|
-
if
|
|
4583
|
+
if (
|
|
4584
|
+
companion_status.get("setup_pending")
|
|
4585
|
+
and sys.stdin.isatty()
|
|
4586
|
+
and os.environ.get("ATMEM_NONINTERACTIVE") != "1"
|
|
4587
|
+
):
|
|
4532
4588
|
_interactive_atbot_setup(atbot_manager)
|
|
4533
4589
|
companion = atbot_manager.ensure_running()
|
|
4534
4590
|
server = ControlDashboardServer(
|