cognitive-memory-layer 0.1.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.
Files changed (82) hide show
  1. cognitive_memory_layer-0.1.0/.editorconfig +15 -0
  2. cognitive_memory_layer-0.1.0/.gitignore +13 -0
  3. cognitive_memory_layer-0.1.0/.pre-commit-config.yaml +22 -0
  4. cognitive_memory_layer-0.1.0/CHANGELOG.md +78 -0
  5. cognitive_memory_layer-0.1.0/CONTRIBUTING.md +171 -0
  6. cognitive_memory_layer-0.1.0/LICENSE +674 -0
  7. cognitive_memory_layer-0.1.0/PKG-INFO +269 -0
  8. cognitive_memory_layer-0.1.0/README.md +217 -0
  9. cognitive_memory_layer-0.1.0/SECURITY.md +16 -0
  10. cognitive_memory_layer-0.1.0/coverage.xml +1602 -0
  11. cognitive_memory_layer-0.1.0/docs/.gitkeep +0 -0
  12. cognitive_memory_layer-0.1.0/docs/api-reference.md +63 -0
  13. cognitive_memory_layer-0.1.0/docs/configuration.md +88 -0
  14. cognitive_memory_layer-0.1.0/docs/examples.md +54 -0
  15. cognitive_memory_layer-0.1.0/docs/getting-started.md +52 -0
  16. cognitive_memory_layer-0.1.0/examples/.gitkeep +0 -0
  17. cognitive_memory_layer-0.1.0/examples/agent_integration.py +62 -0
  18. cognitive_memory_layer-0.1.0/examples/async_example.py +24 -0
  19. cognitive_memory_layer-0.1.0/examples/chat_with_memory.py +61 -0
  20. cognitive_memory_layer-0.1.0/examples/embedded_mode.py +27 -0
  21. cognitive_memory_layer-0.1.0/examples/quickstart.py +27 -0
  22. cognitive_memory_layer-0.1.0/pyproject.toml +112 -0
  23. cognitive_memory_layer-0.1.0/src/cml/__init__.py +46 -0
  24. cognitive_memory_layer-0.1.0/src/cml/_version.py +1 -0
  25. cognitive_memory_layer-0.1.0/src/cml/async_client.py +1066 -0
  26. cognitive_memory_layer-0.1.0/src/cml/client.py +1124 -0
  27. cognitive_memory_layer-0.1.0/src/cml/config.py +89 -0
  28. cognitive_memory_layer-0.1.0/src/cml/embedded.py +469 -0
  29. cognitive_memory_layer-0.1.0/src/cml/embedded_config.py +60 -0
  30. cognitive_memory_layer-0.1.0/src/cml/embedded_utils.py +91 -0
  31. cognitive_memory_layer-0.1.0/src/cml/exceptions.py +121 -0
  32. cognitive_memory_layer-0.1.0/src/cml/integrations/__init__.py +5 -0
  33. cognitive_memory_layer-0.1.0/src/cml/integrations/openai_helper.py +108 -0
  34. cognitive_memory_layer-0.1.0/src/cml/models/__init__.py +50 -0
  35. cognitive_memory_layer-0.1.0/src/cml/models/enums.py +57 -0
  36. cognitive_memory_layer-0.1.0/src/cml/models/memory.py +3 -0
  37. cognitive_memory_layer-0.1.0/src/cml/models/requests.py +73 -0
  38. cognitive_memory_layer-0.1.0/src/cml/models/responses.py +152 -0
  39. cognitive_memory_layer-0.1.0/src/cml/py.typed +0 -0
  40. cognitive_memory_layer-0.1.0/src/cml/storage/__init__.py +11 -0
  41. cognitive_memory_layer-0.1.0/src/cml/storage/sqlite_store.py +401 -0
  42. cognitive_memory_layer-0.1.0/src/cml/transport/__init__.py +5 -0
  43. cognitive_memory_layer-0.1.0/src/cml/transport/http.py +310 -0
  44. cognitive_memory_layer-0.1.0/src/cml/transport/retry.py +111 -0
  45. cognitive_memory_layer-0.1.0/src/cml/utils/__init__.py +12 -0
  46. cognitive_memory_layer-0.1.0/src/cml/utils/deprecation.py +50 -0
  47. cognitive_memory_layer-0.1.0/src/cml/utils/logging.py +38 -0
  48. cognitive_memory_layer-0.1.0/src/cml/utils/serialization.py +44 -0
  49. cognitive_memory_layer-0.1.0/tests/__init__.py +1 -0
  50. cognitive_memory_layer-0.1.0/tests/conftest.py +146 -0
  51. cognitive_memory_layer-0.1.0/tests/e2e/__init__.py +1 -0
  52. cognitive_memory_layer-0.1.0/tests/e2e/conftest.py +50 -0
  53. cognitive_memory_layer-0.1.0/tests/e2e/test_chat_flow.py +34 -0
  54. cognitive_memory_layer-0.1.0/tests/e2e/test_migration.py +29 -0
  55. cognitive_memory_layer-0.1.0/tests/embedded/__init__.py +1 -0
  56. cognitive_memory_layer-0.1.0/tests/embedded/conftest.py +24 -0
  57. cognitive_memory_layer-0.1.0/tests/embedded/test_lifecycle.py +51 -0
  58. cognitive_memory_layer-0.1.0/tests/embedded/test_lite_mode.py +56 -0
  59. cognitive_memory_layer-0.1.0/tests/integration/__init__.py +1 -0
  60. cognitive_memory_layer-0.1.0/tests/integration/conftest.py +67 -0
  61. cognitive_memory_layer-0.1.0/tests/integration/test_admin.py +55 -0
  62. cognitive_memory_layer-0.1.0/tests/integration/test_batch.py +38 -0
  63. cognitive_memory_layer-0.1.0/tests/integration/test_namespace.py +14 -0
  64. cognitive_memory_layer-0.1.0/tests/integration/test_sessions.py +38 -0
  65. cognitive_memory_layer-0.1.0/tests/integration/test_stats.py +20 -0
  66. cognitive_memory_layer-0.1.0/tests/integration/test_turn.py +37 -0
  67. cognitive_memory_layer-0.1.0/tests/integration/test_update_forget.py +37 -0
  68. cognitive_memory_layer-0.1.0/tests/integration/test_write_read.py +35 -0
  69. cognitive_memory_layer-0.1.0/tests/unit/__init__.py +1 -0
  70. cognitive_memory_layer-0.1.0/tests/unit/test_client_health.py +57 -0
  71. cognitive_memory_layer-0.1.0/tests/unit/test_client_memory.py +216 -0
  72. cognitive_memory_layer-0.1.0/tests/unit/test_config.py +84 -0
  73. cognitive_memory_layer-0.1.0/tests/unit/test_embedded.py +52 -0
  74. cognitive_memory_layer-0.1.0/tests/unit/test_exceptions.py +40 -0
  75. cognitive_memory_layer-0.1.0/tests/unit/test_import.py +64 -0
  76. cognitive_memory_layer-0.1.0/tests/unit/test_logging.py +14 -0
  77. cognitive_memory_layer-0.1.0/tests/unit/test_models.py +129 -0
  78. cognitive_memory_layer-0.1.0/tests/unit/test_phase5.py +326 -0
  79. cognitive_memory_layer-0.1.0/tests/unit/test_phase6.py +252 -0
  80. cognitive_memory_layer-0.1.0/tests/unit/test_retry.py +62 -0
  81. cognitive_memory_layer-0.1.0/tests/unit/test_serialization.py +27 -0
  82. cognitive_memory_layer-0.1.0/tests/unit/test_transport.py +229 -0
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 4
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.{yml,yaml,toml}]
12
+ indent_size = 2
13
+
14
+ [*.md]
15
+ trim_trailing_whitespace = false
@@ -0,0 +1,13 @@
1
+ # Build artifacts
2
+ dist/
3
+ build/
4
+ *.egg-info/
5
+ .eggs/
6
+ *.egg
7
+
8
+ # Caches
9
+ .mypy_cache/
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ htmlcov/
13
+ .coverage
@@ -0,0 +1,22 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.8.0
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v1.13.0
11
+ hooks:
12
+ - id: mypy
13
+ additional_dependencies: [pydantic>=2.0, httpx>=0.27]
14
+
15
+ - repo: https://github.com/pre-commit/pre-commit-hooks
16
+ rev: v5.0.0
17
+ hooks:
18
+ - id: trailing-whitespace
19
+ - id: end-of-file-fixer
20
+ - id: check-yaml
21
+ - id: check-toml
22
+ - id: check-added-large-files
@@ -0,0 +1,78 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ #### Phase 1: Project setup
13
+ - Initial project structure and build configuration (Hatchling, src layout)
14
+ - Package `cml` with sync and async client classes (`CognitiveMemoryLayer`, `AsyncCognitiveMemoryLayer`)
15
+ - Development tooling: ruff, mypy, pytest, pre-commit, editorconfig
16
+ - CI workflows: py-cml-test (Python 3.11–3.13), py-cml-lint, py-cml-publish (on `py-cml-v*` tags)
17
+ - README, CONTRIBUTING, and CHANGELOG
18
+
19
+ #### Phase 2: Core client SDK
20
+ - **Configuration:** Pydantic `CMLConfig` with validation; loading from direct params, env vars (`CML_*`), and `.env` (python-dotenv)
21
+ - **Exceptions:** Full hierarchy — `CMLError` (with `status_code`, `response_body`), `AuthenticationError`, `AuthorizationError`, `NotFoundError`, `ValidationError`, `RateLimitError` (with `retry_after`), `ServerError`, `ConnectionError`, `TimeoutError`
22
+ - **Transport:** Sync `HTTPTransport` and async `AsyncHTTPTransport` (httpx), path prefix `/api/v1`, standard headers (API key, tenant ID, User-Agent), status-code mapping to exceptions
23
+ - **Retry:** Exponential backoff with jitter for 5xx, 429, connection, and timeout; `RateLimitError` respects `Retry-After` header; retry integrated in transport `request()`
24
+ - **Models:** Enums `MemoryType`, `MemoryStatus`, `MemorySource`, `OperationType`; request models (`WriteRequest`, `ReadRequest`, `TurnRequest`, `UpdateRequest`, `ForgetRequest`); response models (`HealthResponse`, `WriteResponse`, `ReadResponse`, `TurnResponse`, etc., `MemoryItem`)
25
+ - **Clients:** Context manager support (`with` / `async with`), `close()`, `health()` returning `HealthResponse`
26
+ - Unit tests for config, exceptions, retry, transport (mocked), and client health (29 tests)
27
+
28
+ #### Phase 3: Memory operations
29
+ - **Memory API:** `write`, `read`, `turn`, `update`, `forget`, `stats` on both sync and async clients
30
+ - **Sessions:** `create_session`, `get_session_context`; request/response models `CreateSessionRequest`, `SessionContextResponse`
31
+ - **Convenience:** `get_context` (read with format=llm_context), `remember` (alias for write), `search` (alias for read)
32
+ - **Admin:** `delete_all(confirm=True)` (requires confirm; server route may be added later)
33
+ - **Validation:** `forget()` requires at least one of `memory_ids`, `query`, or `before`; docstrings with Args, Returns, Raises
34
+ - Unit tests for memory operations (mocked transport): write/read responses, forget/delete_all validation, get_context, remember/search delegation
35
+
36
+ #### Phase 4: Embedded mode
37
+ - **EmbeddedCognitiveMemoryLayer:** In-process CML engine with same API as HTTP client (write, read, turn, update, forget, stats, get_context, remember, search, create_session, get_session_context, delete_all)
38
+ - **EmbeddedConfig:** Storage mode (lite/standard/full), database, embedding, and LLM config; lite mode uses SQLite + local embeddings
39
+ - **SQLite memory store:** `cml.storage.sqlite_store.SQLiteMemoryStore` implementing engine MemoryStoreBase; in-memory cosine similarity for vector search (~10k records)
40
+ - **Lite mode:** Zero-config `EmbeddedCognitiveMemoryLayer()` uses in-memory SQLite and sentence-transformers; optional `db_path` for persistence
41
+ - **Background workers:** Optional asyncio tasks for consolidation and forgetting when `auto_consolidate` / `auto_forget` are True
42
+ - **Export/import:** `cml.embedded_utils.export_memories_async`, `import_memories_async` (and sync wrappers) for migration between embedded and server
43
+ - **Parent engine:** HippocampalStore accepts MemoryStoreBase; MemoryOrchestrator.create_lite(episodic_store, embedding_client, llm_client); NoOpGraphStore and NoOpFactStore for lite
44
+ - Unit tests for embedded config and mocked orchestrator
45
+
46
+ #### Phase 5: Advanced features
47
+ - **Admin operations:** `consolidate(tenant_id=..., user_id=...)` and `run_forgetting(tenant_id=..., user_id=..., dry_run=..., max_memories=...)` (dashboard routes; require admin API key)
48
+ - **Batch operations:** `batch_write(items, session_id=..., namespace=...)` (sequential) and `batch_read(queries, max_results=..., format=...)` (concurrent on async, sequential on sync)
49
+ - **Tenant management:** `set_tenant(tenant_id)`, `tenant_id` property, `list_tenants()` (admin only)
50
+ - **Event log:** `get_events(limit=..., page=..., event_type=..., since=...)` (admin only)
51
+ - **Component health:** `component_health()` (admin only)
52
+ - **Namespace isolation:** `with_namespace(namespace)` returning `NamespacedClient` / `AsyncNamespacedClient` that inject namespace into write/update/batch_write
53
+ - **Memory iteration:** `iter_memories(memory_types=..., status=..., batch_size=...)` yielding `MemoryItem` with pagination (admin only)
54
+ - **OpenAI integration:** `cml.integrations.CMLOpenAIHelper(memory_client, openai_client, model=...)` with `chat(user_message, session_id=..., system_prompt=..., extra_messages=...)`; optional `MemoryProvider` protocol
55
+ - Unit tests for Phase 5 (mocked transport)
56
+
57
+ #### Phase 6: Developer experience
58
+ - **Structured errors:** CMLError and subclasses include optional `suggestion`, `request_id`; `_raise_for_status` passes actionable suggestions per status code
59
+ - **Logging:** `cml.utils.logging` with `configure_logging(level, handler)`, `_redact()`; DEBUG log for request/response timing in transport; DEBUG/WARNING in retry
60
+ - **Graceful degradation:** `read_safe(query, **kwargs)` on sync and async clients returns empty ReadResponse on ConnectionError/TimeoutError
61
+ - **TypedDict:** `ConsolidationResult`, `ForgettingResult` in models for admin return types
62
+ - **Response __str__:** ReadResponse, WriteResponse, StatsResponse have human-readable `__str__`
63
+ - **Serialization:** `CMLJSONEncoder`, `serialize_for_api()` in `cml.utils.serialization`
64
+ - **Session context manager:** `memory.session(name=..., ttl_hours=...)` (sync and async) yielding SessionScope / AsyncSessionScope with write, read, turn, remember
65
+ - **HTTP/2 and limits:** httpx Client/AsyncClient created with `http2=True` and `Limits(max_connections=100, ...)`
66
+ - **Deprecation:** `cml.utils.deprecation.deprecated(alternative, removal_version)` decorator
67
+ - **Thread safety:** Sync client uses `threading.RLock` in `set_tenant()`
68
+ - **Async loop check:** Async client stores creation event loop and raises RuntimeError if used in a different loop
69
+ - Unit tests for Phase 6 (exceptions, logging, read_safe, __str__, serialization, session, deprecation, thread safety, event loop)
70
+
71
+ #### Phase 8: Documentation and publishing
72
+ - **README:** PyPI and Python version badges, one-line tagline, Documentation links to getting-started, api-reference, configuration, examples
73
+ - **Docs:** getting-started.md, api-reference.md, configuration.md, examples.md in packages/py-cml/docs/
74
+ - **Examples:** quickstart.py, chat_with_memory.py, async_example.py, embedded_mode.py, agent_integration.py in packages/py-cml/examples/
75
+ - **GitHub:** Issue templates (bug_report, feature_request), pull_request_template with Summary, Changes, Testing, Documentation checklists
76
+ - **SECURITY.md:** Supported versions, report via GitHub Security Advisories
77
+ - **CONTRIBUTING:** Releasing py-cml section (version bump, tag py-cml-v*, PyPI publish); fork/venv in dev setup; PR checklist alignment
78
+ - Publish workflow (py-cml-publish.yml on py-cml-v* tag) already in place; no code changes
@@ -0,0 +1,171 @@
1
+ # Contributing to py-cml
2
+
3
+ Thanks for your interest in the CognitiveMemoryLayer Python SDK. This guide covers development setup and workflow for the `packages/py-cml` package.
4
+
5
+ ## Development setup
6
+
7
+ 1. Fork and clone the CognitiveMemoryLayer repository (or work in a branch if you have write access).
8
+ 2. Create a virtual environment (recommended): `python -m venv .venv` then activate it.
9
+ 3. Install the package in editable mode with dev dependencies.
10
+
11
+ From the **repository root**:
12
+
13
+ ```bash
14
+ pip install -e "packages/py-cml[dev]"
15
+ ```
16
+
17
+ Or from inside the package:
18
+
19
+ ```bash
20
+ cd packages/py-cml
21
+ pip install -e ".[dev]"
22
+ ```
23
+
24
+ This installs the package in editable mode with dev dependencies (pytest, ruff, mypy, pre-commit). Run `pre-commit install` to enable hooks.
25
+
26
+ ## Running tests
27
+
28
+ From `packages/py-cml`:
29
+
30
+ **Unit tests (default; no server required):**
31
+
32
+ ```bash
33
+ pytest tests/unit/ -v
34
+ pytest tests/unit/ -v --cov=cml --cov-report=term-missing --cov-branch
35
+ ```
36
+
37
+ Unit tests cover config, exceptions, retry logic, transport (including 403/422/429/500 and connection/timeout mapping), models (serialization), client health and memory operations (mocked), serialization, and logging. CI runs only unit tests on every push.
38
+
39
+ **Integration tests** (require a running CML server):
40
+
41
+ ```bash
42
+ export CML_TEST_URL=http://localhost:8000 # optional
43
+ export CML_TEST_API_KEY=your-key # optional
44
+ pytest tests/integration/ -v -m integration
45
+ ```
46
+
47
+ **Embedded tests** (require `pip install -e ".[dev,embedded]"` and CML engine):
48
+
49
+ ```bash
50
+ pytest tests/embedded/ -v -m embedded
51
+ ```
52
+
53
+ **E2E tests** (require live server):
54
+
55
+ ```bash
56
+ pytest tests/e2e/ -v -m e2e
57
+ ```
58
+
59
+ **Run everything except integration/embedded/e2e:**
60
+
61
+ ```bash
62
+ pytest -m "not integration and not embedded and not e2e" -v
63
+ ```
64
+
65
+ Shared fixtures live in `tests/conftest.py` (`test_config`, `mock_config`, `sync_client`, `async_client`, and mock response helpers). Integration tests use `live_client` from `tests/integration/conftest.py` and skip if the server is unreachable.
66
+
67
+ ## Code style and type checking
68
+
69
+ - **Ruff** — linting and formatting:
70
+ ```bash
71
+ ruff check src/ tests/
72
+ ruff format src/ tests/
73
+ ```
74
+
75
+ - **mypy** — type checking (strict):
76
+ ```bash
77
+ mypy src/cml/
78
+ ```
79
+
80
+ Configuration for ruff and mypy lives in `pyproject.toml`.
81
+
82
+ ## Pre-commit hooks
83
+
84
+ Install and run pre-commit (from `packages/py-cml` or repo root with config path):
85
+
86
+ ```bash
87
+ pre-commit install
88
+ pre-commit run --all-files
89
+ ```
90
+
91
+ Hooks run ruff (check + format), mypy, and generic checks (trailing whitespace, YAML/TOML, etc.).
92
+
93
+ ## Pull request process
94
+
95
+ 1. Create a branch from `main`, make changes in `packages/py-cml/`.
96
+ 2. Add or update tests; ensure `pytest tests/unit/`, `mypy src/cml/`, and `ruff check src/ tests/` pass.
97
+ 3. Update docstrings, README, or CHANGELOG as applicable (see PR template checklist).
98
+ 4. Open a PR. CI runs py-cml tests and lint when paths under `packages/py-cml/**` or the workflow file change.
99
+ 5. Get review approval and merge.
100
+
101
+ ## Commit message conventions
102
+
103
+ - `feat(cml): ...` — new feature
104
+ - `fix(cml): ...` — bug fix
105
+ - `docs(cml): ...` — documentation
106
+ - `test(cml): ...` — tests
107
+ - `chore(py-cml): ...` — build, CI, tooling
108
+
109
+ ## Publishing the package to PyPI
110
+
111
+ Releases are published to PyPI when a tag matching `py-cml-v*` is pushed. The workflow (`.github/workflows/py-cml.yml`) uses **PyPI trusted publishing (OIDC)**; no API tokens are stored in the repo.
112
+
113
+ ### Prerequisites (one-time)
114
+
115
+ - **PyPI:** Add a [trusted publisher](https://docs.pypi.org/trusted-publishers/) (or pending publisher) for the project `cognitive-memory-layer`:
116
+ - **Repository:** `owner/CognitiveMemoryLayer`
117
+ - **Workflow name:** `py-cml.yml`
118
+ - **Environment name:** `pypi`
119
+ - **GitHub:** Create an environment named **`pypi`** under **Settings → Environments** (no secrets required for trusted publishing).
120
+
121
+ ### Before each release
122
+
123
+ 1. **Bump version** in `packages/py-cml/pyproject.toml` and `packages/py-cml/src/cml/_version.py` (e.g. `0.1.0` → `0.1.1`).
124
+ 2. **Update CHANGELOG.md** — add a `## [X.Y.Z] - YYYY-MM-DD` section and move entries from Unreleased.
125
+ 3. **Commit and push to `main`:** e.g. `chore(py-cml): prepare release v0.1.1`
126
+
127
+ ### Ways to publish
128
+
129
+ **Option A — From GitHub Actions (no local tag needed)**
130
+
131
+ 1. Go to **Actions** → **py-cml: CI and release** → **Run workflow**.
132
+ 2. Choose branch **main** (or the branch you pushed the version bump to).
133
+ 3. Enter **Version to release** (e.g. `0.1.1`). Leave it empty only if you just want to run lint/test/build.
134
+ 4. Click **Run workflow**.
135
+ 5. **Two runs:** The first run (manual) only runs **Create release tag** and pushes the tag; lint/test/build/publish are skipped. The **tag push triggers a second run** where only **Build and publish to PyPI** runs. In the Actions list, find the run triggered by the tag (e.g. "Tag py-cml-v0.1.1 pushed" or similar) and confirm that job succeeded.
136
+
137
+ **Option B — From the command line**
138
+
139
+ 1. From your repo root (on `main`, with the version bump already pushed):
140
+ ```bash
141
+ git pull origin main
142
+ git tag py-cml-v0.1.1 # use the same version as in pyproject.toml
143
+ git push origin py-cml-v0.1.1
144
+ ```
145
+ 2. The push triggers the workflow; the **Build and publish to PyPI** job runs and uploads the package.
146
+
147
+ **Option C — From GitHub Releases**
148
+
149
+ 1. After pushing the version bump to `main`, go to **Releases** → **Draft a new release**.
150
+ 2. Choose **Tag:** create a new tag `py-cml-v0.1.1` from `main`.
151
+ 3. Set the release title (e.g. `v0.1.1`) and paste the CHANGELOG section. Publish the release.
152
+ 4. Creating the tag (via the release) pushes it; the workflow runs and publishes to PyPI.
153
+
154
+ ### After publishing
155
+
156
+ - **Optional:** If you used Option B or A, create a **GitHub Release** from the new tag and paste the CHANGELOG section.
157
+ - **Verify:** `pip install cognitive-memory-layer==0.1.1` then `python -c "from cml import CognitiveMemoryLayer; print('OK')"`.
158
+
159
+ ### Troubleshooting
160
+
161
+ - **PyPI still shows "0 projects"**
162
+ Check that the **tag-triggered** run (the second run after you used Option A) exists and that **Build and publish to PyPI** completed successfully. If that run is missing, the tag push may not have triggered the workflow (e.g. path filters); use Option B to push the tag from your machine and confirm the run appears.
163
+ - **Pending publishers:** Use only the publisher for **workflow `py-cml.yml`** and **environment `pypi`**. If you have a pending publisher for `py-cml-publish.yml`, remove it (that workflow was merged into `py-cml.yml`).
164
+
165
+ ### TestPyPI (optional)
166
+
167
+ To try the release flow without publishing to production PyPI: add a trusted publisher for **TestPyPI** with the same workflow and environment, then push a tag (e.g. `py-cml-v0.1.0a1`) or use **Run workflow** with a pre-release version. Install with `pip install -i https://test.pypi.org/simple/ cognitive-memory-layer==0.1.0a1`.
168
+
169
+ ## General repository guidelines
170
+
171
+ For broader contribution guidelines (code of conduct, issue templates, repository structure), see the root [CONTRIBUTING.md](../../CONTRIBUTING.md) of the CognitiveMemoryLayer repository.