mneme-cli 0.5.0__tar.gz → 0.5.2__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.
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/AGENTS.md +169 -1
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/CHANGELOG.md +78 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/CLAUDE.md +1 -1
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/CODER.md +1 -1
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/EXAMPLES.md +2 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/FEATURES.md +8 -1
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/PKG-INFO +103 -19
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/README.md +100 -16
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/__init__.py +2 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/config.py +2 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/core.py +1020 -58
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/server.py +2 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/README.md +1 -1
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/ui.html +2 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/pyproject.toml +4 -2
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_core.py +529 -4
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/LICENSE +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/MANIFEST.in +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/__main__.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/eu-mdr.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/iso-13485.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/mappings/dds.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/mappings/requirements.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/mappings/risk-register.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/mappings/test-cases.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/profiles/mappings/user-needs.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/search.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/.gitignore +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/AGENTS.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/inbox/.gitkeep +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/index.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/log.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/profiles/README.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/profiles/mappings/.gitkeep +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/schema/entities.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/schema/graph.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/schema/tags.json +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/sources/.gitkeep +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme/templates/workspace/wiki/_templates/page.md +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/mneme_cli.egg-info/SOURCES.txt +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/setup.cfg +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/__init__.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_agent_loop.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_bug_regressions.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_ingest_csv.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_profile.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_schema_search.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_search.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_tornado_lint.py +0 -0
- {mneme_cli-0.5.0 → mneme_cli-0.5.2}/tests/test_trace.py +0 -0
|
@@ -213,6 +213,10 @@ out manually, then run `resync-resolve`.
|
|
|
213
213
|
mneme tags suggest <client>/<page> # build tag packet
|
|
214
214
|
mneme tags suggest <client>/<page> --json # raw dict
|
|
215
215
|
mneme tags apply <client>/<page> --add t1,t2 --remove t3
|
|
216
|
+
|
|
217
|
+
# Bulk variants -- packet up to N pages in one round-trip
|
|
218
|
+
mneme tags bulk-suggest --client <c> --filter req- --limit 50 --out packet.md
|
|
219
|
+
mneme tags bulk-apply response.json # response: {"pages": [{wiki_path, add, remove}, ...]}
|
|
216
220
|
```
|
|
217
221
|
|
|
218
222
|
`mneme tags suggest` builds a **tag packet**: the page content, current
|
|
@@ -245,6 +249,124 @@ mneme tags list # all tags + counts
|
|
|
245
249
|
mneme tags merge <old> <new> # rename across all pages
|
|
246
250
|
```
|
|
247
251
|
|
|
252
|
+
### 3.7 ENTITY — agent-driven classification
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
mneme entity suggest --client <c> --limit 50 # classification packet
|
|
256
|
+
mneme entity apply --id iso-13485 --type standard # one at a time
|
|
257
|
+
mneme entity bulk-apply classifications.json # batch
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`mneme entity suggest` builds an **entity packet**: every `unknown`-typed
|
|
261
|
+
entity, the workspace's current type distribution, the valid type
|
|
262
|
+
vocabulary, an example wiki page per entity, and a prompt. The agent
|
|
263
|
+
returns a JSON array of `{id, type}` objects which `bulk-apply` writes
|
|
264
|
+
back atomically. Same philosophy as tags: mneme stays deterministic, the
|
|
265
|
+
LLM does the classification.
|
|
266
|
+
|
|
267
|
+
Valid types: `standard`, `company`, `person`, `product`, `technology`,
|
|
268
|
+
`concept`, `brand`, `unknown`.
|
|
269
|
+
|
|
270
|
+
### 3.8 HOME — generated landing page
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
mneme home --client <c> # wiki/<c>/HOME.md
|
|
274
|
+
mneme home --all-clients # wiki/HOME.md (cross-client)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Generates an Obsidian-friendly navigation hub with Dataview queries
|
|
278
|
+
(group by type, by ID prefix like `REQ-*` / `DDS-*`, top tags) and a
|
|
279
|
+
plain-markdown `<details>` fallback so the page is useful outside
|
|
280
|
+
Obsidian. Run after a large ingest, or whenever the wiki's shape
|
|
281
|
+
changes meaningfully.
|
|
282
|
+
|
|
283
|
+
### 3.9 TRACE — linking the full V-model chain
|
|
284
|
+
|
|
285
|
+
The trace chain a notified body expects has two legs that both terminate
|
|
286
|
+
at code and tests:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
UN ──implemented-by──┐
|
|
290
|
+
├──> REQ ──detailed-in──> DDS ──implemented-in──> codebase
|
|
291
|
+
RMA ──mitigated-by────┘ └──verified-by───> tests
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The first three links (UN→REQ, RMA→REQ, REQ→DDS) are created
|
|
295
|
+
automatically by the CSV mappings in `profiles/mappings/` (or by
|
|
296
|
+
`mneme trace add` when ingesting structured sources). The last two
|
|
297
|
+
links (DDS→codebase, DDS→tests) close the V-model and are the agent's
|
|
298
|
+
responsibility when a user passes you one or more repositories.
|
|
299
|
+
|
|
300
|
+
**When the user passes you a repo path, you must:**
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# 1. Inventory: what code modules / test files exist?
|
|
304
|
+
mneme scan-repo <repo-path> <client>
|
|
305
|
+
# → reports which wiki pages reference the repo's modules, and which do not.
|
|
306
|
+
|
|
307
|
+
# 2. For each DDS page that corresponds to a code module, add the link.
|
|
308
|
+
# The target is a git URL or an absolute repo path; mneme treats it
|
|
309
|
+
# as an opaque string (not a wiki slug) — the target may live outside
|
|
310
|
+
# the workspace.
|
|
311
|
+
mneme trace add <client>/dds-cyb-001 \
|
|
312
|
+
"github.com/<org>/<repo>/blob/main/src/auth/password_policy.py" \
|
|
313
|
+
implemented-in
|
|
314
|
+
|
|
315
|
+
# 3. For each DDS page that has a corresponding test, add the link.
|
|
316
|
+
# The test target can be a wiki page (for test-plan docs) or an
|
|
317
|
+
# external path (for a test file in a repo).
|
|
318
|
+
mneme trace add <client>/dds-cyb-001 <client>/test-auth-001 verified-by
|
|
319
|
+
mneme trace add <client>/dds-cyb-001 \
|
|
320
|
+
"github.com/<org>/<repo>/blob/main/tests/test_password_policy.py" \
|
|
321
|
+
verified-by
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Do this for every DDS page that has implementing code or a verifying
|
|
325
|
+
test. When there are tens or hundreds of links to create (typical for
|
|
326
|
+
a real medical-device codebase):
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
# Batch approach — the agent parses the repo, maps DDS → files,
|
|
330
|
+
# then writes a shell script of `mneme trace add` lines and runs it.
|
|
331
|
+
# mneme has no bulk-trace-add subcommand yet; scripting is the way.
|
|
332
|
+
for pair in dds-cyb-001:src/auth/password_policy.py \
|
|
333
|
+
dds-cyb-002:src/auth/mfa.py \
|
|
334
|
+
dds-cyb-003:src/auth/rate_limiter.py; do
|
|
335
|
+
dds=${pair%%:*}; file=${pair##*:}
|
|
336
|
+
mneme trace add <client>/$dds "<repo-url>/$file" implemented-in
|
|
337
|
+
done
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Verify the chain is now complete:**
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
mneme trace gaps <client>
|
|
344
|
+
# → should report 0 hazards without mitigation, 0 DDS without
|
|
345
|
+
# implementation link, 0 DDS without verification link
|
|
346
|
+
|
|
347
|
+
mneme trace show <client>/un-001
|
|
348
|
+
# → UN.001
|
|
349
|
+
# implemented-by -> REQ.SYS.001
|
|
350
|
+
# detailed-in -> DDS.CYB.001
|
|
351
|
+
# implemented-in -> github.com/.../password_policy.py
|
|
352
|
+
# verified-by -> github.com/.../test_password_policy.py
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Relationship vocabulary — use exactly these strings:**
|
|
356
|
+
|
|
357
|
+
| Relationship | From → To | Semantics |
|
|
358
|
+
|---|---|---|
|
|
359
|
+
| `implemented-by` | UN → REQ | The user need is met by this requirement |
|
|
360
|
+
| `mitigated-by` | RMA → REQ | The hazard is mitigated by this requirement |
|
|
361
|
+
| `derived-from` | REQ → UN / REQ → higher-level REQ | Parent requirement |
|
|
362
|
+
| `detailed-in` | REQ → DDS | The requirement is elaborated by this design spec |
|
|
363
|
+
| `implemented-in` | DDS → codebase | The design spec is realised by this source file / module |
|
|
364
|
+
| `verified-by` | DDS → test / REQ → test | The spec/requirement is verified by this test |
|
|
365
|
+
| `validated-by` | DDS → clinical/usability study | Validation (not verification) evidence |
|
|
366
|
+
|
|
367
|
+
Stick to this vocabulary. Custom relationships confuse downstream
|
|
368
|
+
matrix exports and break the default `trace gaps` heuristics.
|
|
369
|
+
|
|
248
370
|
---
|
|
249
371
|
|
|
250
372
|
## 4. Profiles and the writing-style contract
|
|
@@ -537,7 +659,53 @@ file.
|
|
|
537
659
|
Stop conditions: inbox is empty, `mneme stats` shows a plausible page
|
|
538
660
|
count, and `mneme lint` reports no critical issues.
|
|
539
661
|
|
|
540
|
-
### 6.6
|
|
662
|
+
### 6.6 Close the V-model by linking DDS to codebase and tests
|
|
663
|
+
|
|
664
|
+
The user has just handed you one or more repositories. Your job is to
|
|
665
|
+
connect every DDS page to the implementing source file(s) and the
|
|
666
|
+
verifying test file(s) so `mneme trace show` walks end-to-end from a
|
|
667
|
+
user need / hazard all the way to the exact line of code and the exact
|
|
668
|
+
test that exercises it.
|
|
669
|
+
|
|
670
|
+
```
|
|
671
|
+
1. mneme profile show # sanity check
|
|
672
|
+
2. mneme trace matrix <client> # baseline — which DDS exist?
|
|
673
|
+
3. For each repo the user passes:
|
|
674
|
+
a. mneme scan-repo <repo-path> <client> # surface module gaps
|
|
675
|
+
b. Read the repo tree and README yourself.
|
|
676
|
+
Build a mapping: DDS ID -> [source files]
|
|
677
|
+
DDS ID -> [test files]
|
|
678
|
+
Prefer explicit evidence (comments referencing the DDS ID,
|
|
679
|
+
module/function names that mirror the DDS title, docstrings
|
|
680
|
+
that cite the requirement). When evidence is weak, flag the
|
|
681
|
+
DDS as ambiguous and surface it — do not guess.
|
|
682
|
+
4. For each confident (DDS, file) pair:
|
|
683
|
+
mneme trace add <client>/<dds-slug> "<repo-url-or-path>/<file>" implemented-in
|
|
684
|
+
mneme trace add <client>/<dds-slug> "<repo-url-or-path>/<test-file>" verified-by
|
|
685
|
+
Batch these in a shell loop — there is no bulk-trace-add subcommand.
|
|
686
|
+
5. mneme trace gaps <client> # should trend to zero
|
|
687
|
+
6. mneme trace show <client>/un-001 # spot-check: full chain
|
|
688
|
+
from UN to test file?
|
|
689
|
+
7. mneme trace matrix <client> --csv --out trace-matrix.csv
|
|
690
|
+
# DHF-ready export
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
Stop conditions: (a) every DDS page either has both `implemented-in`
|
|
694
|
+
and `verified-by` trace links OR is explicitly flagged ambiguous in a
|
|
695
|
+
report to the user, AND (b) `trace gaps` reports zero open chains.
|
|
696
|
+
|
|
697
|
+
Hard rules:
|
|
698
|
+
- Do not fabricate file paths. If the repo has no file matching a DDS,
|
|
699
|
+
report the gap and stop — the user must either point you at another
|
|
700
|
+
repo or add the link manually.
|
|
701
|
+
- Trace targets for external files are opaque strings. Use a stable
|
|
702
|
+
form the team can resolve later (a git URL with a pinned commit is
|
|
703
|
+
ideal; a bare relative path is fine when the repo lives alongside
|
|
704
|
+
the workspace).
|
|
705
|
+
- Never rewrite a DDS page's body to embed the code link. The link
|
|
706
|
+
lives in `schema/traceability.json` only. Wiki pages stay prose.
|
|
707
|
+
|
|
708
|
+
### 6.7 Pre-submission readiness check before sending to a notified body
|
|
541
709
|
|
|
542
710
|
```
|
|
543
711
|
1. mneme profile show # confirm active profile
|
|
@@ -4,6 +4,51 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.5.2] - 2026-04-14
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **`ingest-dir --preserve-structure` is now the default.** The wiki now
|
|
12
|
+
mirrors the source directory layout unless you pass `--flat`. This avoids
|
|
13
|
+
silent same-basename collisions (e.g. multiple `INSTRUCTIONS.md` files from
|
|
14
|
+
different source directories overwriting each other). Closes suggestion #15.
|
|
15
|
+
- **`mneme ingest` (single-file) also mirrors by default.** When the source
|
|
16
|
+
lives under `sources/<client>/`, its relative position becomes a wiki
|
|
17
|
+
subpath automatically. Pass `--flat` to opt out.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **`mneme profile list`** now discovers profiles correctly. Previously it
|
|
22
|
+
filtered files by `.json` (wrong extension — profiles are markdown) and
|
|
23
|
+
only checked the bundled directory, which meant the shipped `eu-mdr.md`
|
|
24
|
+
and `iso-13485.md` profiles appeared as "No profiles found". Now unions
|
|
25
|
+
workspace + bundled, marks origin, and flags shadowed bundled profiles.
|
|
26
|
+
Closes suggestion #25 discovery bug.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **`ingest-dir --flat`** — explicit opt-out for the new preserve-structure
|
|
31
|
+
default.
|
|
32
|
+
- **`ingest --flat`** — opt-out for the single-file command.
|
|
33
|
+
- **xlsx support is now built-in.** `openpyxl` moved from
|
|
34
|
+
`[project.optional-dependencies].xlsx` to `dependencies`. The `[xlsx]`
|
|
35
|
+
extra is kept for backwards compatibility but is no longer required.
|
|
36
|
+
|
|
37
|
+
### Documentation
|
|
38
|
+
|
|
39
|
+
- **README**: expanded the agent end-to-end example. Step 3 now covers
|
|
40
|
+
bulk tagging (`tags bulk-suggest` + `bulk-apply`), Step 3b adds entity
|
|
41
|
+
typing (`entity suggest` + `bulk-apply`), and Step 3c walks the full
|
|
42
|
+
V-model trace chain (UN→REQ→DDS and RMA→REQ→DDS, terminating at code
|
|
43
|
+
and tests).
|
|
44
|
+
- **AGENTS.md**: new section 3.9 "TRACE — linking the full V-model
|
|
45
|
+
chain" documents the `implemented-in` / `verified-by` relationships
|
|
46
|
+
and the DDS-to-codebase linking agents must perform when the user
|
|
47
|
+
passes repositories. New task template 6.6 "Close the V-model by
|
|
48
|
+
linking DDS to codebase and tests" gives the exact procedure, stop
|
|
49
|
+
conditions, and hard rules (no fabricated paths, trace targets are
|
|
50
|
+
opaque strings, never embed code links in page bodies).
|
|
51
|
+
|
|
7
52
|
## [0.5.0] - 2026-04-13
|
|
8
53
|
|
|
9
54
|
### Breaking Changes
|
|
@@ -58,6 +103,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
58
103
|
- Chunking logic (`chunk_body`, `MAX_CHUNK_SIZE`, frame management).
|
|
59
104
|
- Tantivy-reserved-word query sanitizer (FTS5 has different syntax).
|
|
60
105
|
|
|
106
|
+
## [0.5.1] - 2026-04-14
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
- **`mneme entity suggest` / `entity apply` / `entity bulk-apply`** — agent-driven
|
|
110
|
+
entity classification (same packet pattern as `tags suggest`). Mneme builds a
|
|
111
|
+
packet of unclassified entities + the workspace type taxonomy + example pages;
|
|
112
|
+
the LLM agent classifies; mneme writes the types back atomically.
|
|
113
|
+
- **`mneme tags bulk-suggest` / `tags bulk-apply`** — operate on many pages at
|
|
114
|
+
once. `bulk-suggest --client X --filter req- --limit 50` packets up to 50
|
|
115
|
+
matching pages; agent returns one JSON file; `bulk-apply` runs all the changes
|
|
116
|
+
with per-page error tolerance. Critical for tagging workspaces of hundreds of
|
|
117
|
+
pages.
|
|
118
|
+
- **`mneme home --client <slug>` / `--all-clients`** — generates a `HOME.md`
|
|
119
|
+
navigation hub with Obsidian Dataview queries (group by type, by ID prefix
|
|
120
|
+
like REQ-*/DDS-*, top tags) plus a plain-markdown `<details>` fallback for
|
|
121
|
+
non-Obsidian viewers.
|
|
122
|
+
- **`mneme ingest-dir --preserve-structure`** — mirrors source directory
|
|
123
|
+
hierarchy into wiki subdirectories. `sources/client/REQUIREMENTS/req-001.md`
|
|
124
|
+
becomes `wiki/client/requirements/req-001.md` instead of flattening. Also
|
|
125
|
+
resolves same-basename-different-directory collisions naturally.
|
|
126
|
+
- **`mneme resync` auto-detects subpath** from a source's location under
|
|
127
|
+
`sources/<client>/`, so resyncs of preserve-structure ingests target the
|
|
128
|
+
correct nested wiki page instead of creating a duplicate flat one.
|
|
129
|
+
- **Progress bar** for `ingest-dir` and `ingest-csv` long loops. TTY-aware
|
|
130
|
+
(in-place updates) with non-TTY fallback (periodic line output) so CI logs
|
|
131
|
+
stay readable.
|
|
132
|
+
|
|
133
|
+
### Fixed
|
|
134
|
+
- `mneme status` crashed with `UnboundLocalError` because a local `status` in
|
|
135
|
+
the `agent show` branch shadowed the function name throughout `main()`.
|
|
136
|
+
- `wiki/HOME.md` and `wiki/<client>/HOME.md` are now skipped during HOME
|
|
137
|
+
generation so re-running is idempotent.
|
|
138
|
+
|
|
61
139
|
## [Unreleased]
|
|
62
140
|
|
|
63
141
|
### Added
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mneme - Wiki Protocol
|
|
2
2
|
|
|
3
3
|
> **If you are an LLM agent driving mneme**, read [AGENTS.md](AGENTS.md) **first**. It is the canonical agent protocol: the agent loop, the standard task templates, the sub-agent spawning patterns, and the hard rules you must never violate. CLAUDE.md (this file) describes the wiki layer; AGENTS.md describes the agent's job.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# EXAMPLES.md -
|
|
1
|
+
# EXAMPLES.md - mneme Usage Guide
|
|
2
2
|
|
|
3
3
|
Real-world workflows, core concepts, and entity types used in mneme.
|
|
4
4
|
|
|
@@ -256,7 +256,7 @@ cp ~/old-qms/*.pdf inbox/
|
|
|
256
256
|
# Let tornado figure it out
|
|
257
257
|
mneme tornado --client cardio-monitor
|
|
258
258
|
|
|
259
|
-
# ===
|
|
259
|
+
# === mneme Tornado ===
|
|
260
260
|
#
|
|
261
261
|
# Scanning inbox/... found 50 files
|
|
262
262
|
#
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mneme - Feature Roadmap
|
|
2
2
|
|
|
3
3
|
## Current Features (v0.4.0)
|
|
4
4
|
|
|
@@ -34,6 +34,13 @@
|
|
|
34
34
|
| `mneme tags merge` | Merge one tag into another across all pages |
|
|
35
35
|
| `mneme tags suggest <page>` | Build a *tag packet* for an LLM agent (page content + taxonomy + prompt) |
|
|
36
36
|
| `mneme tags apply <page> --add t1,t2 --remove t3` | Atomic tag update: rewrites frontmatter, updates schema/tags.json, re-syncs FTS5 index |
|
|
37
|
+
| `mneme tags bulk-suggest --client X --filter req- --limit 50` | Bulk tag packet for many pages in one round-trip |
|
|
38
|
+
| `mneme tags bulk-apply response.json` | Apply tag changes from an agent JSON response (per-page error tolerance) |
|
|
39
|
+
| `mneme entity suggest --client X` | Agent-driven entity-classification packet (entities + taxonomy + example pages) |
|
|
40
|
+
| `mneme entity apply --id <id> --type <type>` | Set one entity's type atomically |
|
|
41
|
+
| `mneme entity bulk-apply classifications.json` | Bulk classify entities from a JSON file |
|
|
42
|
+
| `mneme home --client X` / `--all-clients` | Generate a `HOME.md` navigation hub with Dataview queries and plain-markdown fallback |
|
|
43
|
+
| `mneme ingest-dir --preserve-structure` | Mirror source directory hierarchy into wiki subdirectories (resync auto-detects matching subpath) |
|
|
37
44
|
| `mneme diff` | Git-aware diff for a wiki page |
|
|
38
45
|
| `mneme snapshot` | Versioned zip archive of a client + git tag |
|
|
39
46
|
| `mneme dedupe` | Detect near-duplicate wiki pages |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mneme-cli
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: mneme - CLI tool that turns documents into a searchable second brain. Ingest once, query forever.
|
|
5
5
|
Author-email: Tolis Moustaklis <apostolos.moustaklis@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/tolism/mneme
|
|
@@ -29,20 +29,20 @@ Requires-Python: >=3.9
|
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
License-File: LICENSE
|
|
31
31
|
Requires-Dist: portalocker>=2.0.0
|
|
32
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
32
33
|
Provides-Extra: pdf
|
|
33
34
|
Requires-Dist: pymupdf>=1.23.0; extra == "pdf"
|
|
34
35
|
Provides-Extra: xlsx
|
|
35
36
|
Requires-Dist: openpyxl>=3.1.0; extra == "xlsx"
|
|
36
37
|
Provides-Extra: all
|
|
37
38
|
Requires-Dist: pymupdf>=1.23.0; extra == "all"
|
|
38
|
-
Requires-Dist: openpyxl>=3.1.0; extra == "all"
|
|
39
39
|
Provides-Extra: release
|
|
40
40
|
Requires-Dist: build>=1.0.0; extra == "release"
|
|
41
41
|
Requires-Dist: twine>=5.0.0; extra == "release"
|
|
42
42
|
Dynamic: license-file
|
|
43
43
|
|
|
44
44
|
<p align="center">
|
|
45
|
-
<img src="https://raw.githubusercontent.com/tolism/mneme/main/assets/logo.png" alt="
|
|
45
|
+
<img src="https://raw.githubusercontent.com/tolism/mneme/main/assets/logo.png" alt="mneme" width="400">
|
|
46
46
|
</p>
|
|
47
47
|
|
|
48
48
|
<h1 align="center"></h1>
|
|
@@ -167,6 +167,13 @@ One installed CLI serves many projects — each workspace is just a directory.
|
|
|
167
167
|
| `mneme validate writing-style <page>` | Build a *review packet* for an LLM agent to grade a page |
|
|
168
168
|
| `mneme tags suggest <page>` | Build a *tag packet* for an LLM agent to choose tags |
|
|
169
169
|
| `mneme tags apply <page> --add t1,t2 --remove t3` | Atomic tag update (frontmatter + schema + search index) |
|
|
170
|
+
| `mneme tags bulk-suggest --client X --filter req- --limit 50` | Build one *bulk packet* covering many pages |
|
|
171
|
+
| `mneme tags bulk-apply response.json` | Apply tag changes from an agent JSON response |
|
|
172
|
+
| `mneme entity suggest --client X` | Build an *entity-classification packet* for an LLM agent |
|
|
173
|
+
| `mneme entity apply --id <id> --type <type>` | Set one entity's type atomically |
|
|
174
|
+
| `mneme entity bulk-apply classifications.json` | Bulk classify many entities |
|
|
175
|
+
| `mneme home --client X` / `--all-clients` | Generate a `HOME.md` navigation hub (Dataview + fallback) |
|
|
176
|
+
| `mneme ingest-dir --recursive --preserve-structure` | Mirror source directory hierarchy into the wiki |
|
|
170
177
|
| `mneme agent plan --goal "..." --doc-type <t> --client <c>` | Generate a deterministic TODO plan from the active profile |
|
|
171
178
|
| `mneme agent next-task` | Return the next ready task in the active plan |
|
|
172
179
|
| `mneme agent task-done <id>` | Mark a task as done |
|
|
@@ -176,7 +183,7 @@ One installed CLI serves many projects — each workspace is just a directory.
|
|
|
176
183
|
| `mneme stats` | Health overview |
|
|
177
184
|
| `mneme repair` | Fix corrupted archives |
|
|
178
185
|
|
|
179
|
-
**Formats:** `.md`, `.txt`, `.pdf`, `.xlsx` (
|
|
186
|
+
**Formats:** `.md`, `.txt`, `.pdf`, `.xlsx` (built-in), plus `.csv` via `mneme ingest-csv`
|
|
180
187
|
|
|
181
188
|
---
|
|
182
189
|
|
|
@@ -231,38 +238,115 @@ Creates the workspace tree, sets the EU MDR writing-style profile, and initializ
|
|
|
231
238
|
cp -r ~/Downloads/parkinson-research/* inbox/
|
|
232
239
|
mneme tornado --client parkiwatch
|
|
233
240
|
|
|
234
|
-
# Or ingest individual files
|
|
241
|
+
# Or ingest individual files (auto-mirrors sources/<client>/ layout into wiki/)
|
|
235
242
|
mneme ingest research-paper.pdf parkiwatch
|
|
236
|
-
mneme ingest-csv risk-register.csv parkiwatch --mapping risk-register
|
|
237
243
|
mneme ingest spec-table.xlsx parkiwatch # .xlsx renders sheets as markdown tables
|
|
238
|
-
mneme ingest-dir docs/ parkiwatch --recursive # walk subdirectories
|
|
244
|
+
mneme ingest-dir docs/ parkiwatch --recursive # walk subdirectories, preserve structure
|
|
245
|
+
|
|
246
|
+
# Structured CSV ingestion — one row becomes one wiki page + trace links.
|
|
247
|
+
# Mappings live in <workspace>/profiles/mappings/ or are auto-detected.
|
|
248
|
+
mneme ingest-csv user-needs.csv parkiwatch --mapping parkiwatch-user-needs
|
|
249
|
+
mneme ingest-csv requirements.csv parkiwatch --mapping parkiwatch-req
|
|
250
|
+
mneme ingest-csv design-specs.csv parkiwatch --mapping parkiwatch-dds
|
|
251
|
+
mneme ingest-csv risk-register.csv parkiwatch --mapping parkiwatch-rma
|
|
239
252
|
```
|
|
240
253
|
|
|
241
|
-
What happens per ingest: source file → wiki page in `wiki/parkiwatch
|
|
254
|
+
What happens per ingest: source file → wiki page in `wiki/parkiwatch/<mirrored-subpath>/` → frontmatter with auto-extracted proper-noun entities → entry in `index.md` → row in the FTS5 search DB → log entry. CSV ingests additionally create trace links (e.g. UN→REQ `implemented-by`, REQ→DDS `detailed-in`) in `schema/traceability.json`.
|
|
242
255
|
|
|
243
|
-
### Step 3 — Tag
|
|
256
|
+
### Step 3 — Tag many pages at once (LLM agent, bulk)
|
|
244
257
|
|
|
245
|
-
|
|
258
|
+
New pages have only the auto-applied `parkiwatch` client tag. The agent tags them in batches:
|
|
246
259
|
|
|
247
260
|
```bash
|
|
248
|
-
#
|
|
249
|
-
|
|
261
|
+
# 1. Pack up to 30 untagged pages into a single review packet.
|
|
262
|
+
# --filter scopes by wiki_path substring; omit for everything.
|
|
263
|
+
mneme tags bulk-suggest --filter indicators --limit 30 \
|
|
264
|
+
--json --out /tmp/tag-packet.json
|
|
250
265
|
```
|
|
251
266
|
|
|
252
|
-
The packet contains
|
|
267
|
+
The packet contains, for each page: wiki_path, title, current tags, body excerpt, and the existing taxonomy with usage counts. **The LLM reads the packet** and returns a response JSON:
|
|
253
268
|
|
|
254
269
|
```json
|
|
255
|
-
{
|
|
270
|
+
{
|
|
271
|
+
"pages": [
|
|
272
|
+
{"wiki_path": "parkiwatch/indicators/bda_algorithm_description.md",
|
|
273
|
+
"add": ["bradykinesia", "algorithm", "imu", "medical-device"]},
|
|
274
|
+
{"wiki_path": "parkiwatch/indicators/tremor_indicator_dataflow.md",
|
|
275
|
+
"add": ["tremor", "dataflow", "imu", "algorithm"]}
|
|
276
|
+
]
|
|
277
|
+
}
|
|
256
278
|
```
|
|
257
279
|
|
|
258
|
-
|
|
280
|
+
```bash
|
|
281
|
+
# 2. Apply all decisions in one atomic call
|
|
282
|
+
mneme tags bulk-apply /tmp/tag-response.json
|
|
283
|
+
# → Pages updated: 9 Tags added: 42 Tags removed: 0
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Each application rewrites the wiki page frontmatter, updates `schema/tags.json`, re-indexes the page in FTS5, and appends a log entry. Subsequent packets reuse the growing taxonomy, so the vocabulary converges.
|
|
287
|
+
|
|
288
|
+
For single pages use `mneme tags suggest <slug>` + `mneme tags apply <slug> --add a,b,c`.
|
|
289
|
+
|
|
290
|
+
### Step 3b — Classify entities by type (LLM agent)
|
|
291
|
+
|
|
292
|
+
Ingest auto-extracts capitalized proper nouns (e.g. "Parkiwatch", "IEC 62304") into `schema/entities.json` with `type: unknown`. Typing is an LLM judgement call, handled the same packet way as tags:
|
|
259
293
|
|
|
260
294
|
```bash
|
|
261
|
-
|
|
262
|
-
|
|
295
|
+
# 1. Build an entity-classification packet (up to 50 unclassified entities)
|
|
296
|
+
mneme entity suggest --client parkiwatch --limit 50 \
|
|
297
|
+
--json --out /tmp/entity-packet.json
|
|
298
|
+
|
|
299
|
+
# 2. LLM reads the packet and returns classifications:
|
|
300
|
+
# [{"id": "iec-62304", "type": "standard"},
|
|
301
|
+
# {"id": "notified-body", "type": "organization"},
|
|
302
|
+
# {"id": "bradykinesia", "type": "concept"}, ...]
|
|
303
|
+
|
|
304
|
+
# 3. Apply atomically
|
|
305
|
+
mneme entity bulk-apply /tmp/entity-response.json
|
|
306
|
+
# → Entities typed: 47 Errors: 0
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Supported types include `standard`, `organization`, `person`, `concept`, `technology`, `regulation`, or any custom type the profile defines. Typed entities power filtered search and the knowledge graph.
|
|
310
|
+
|
|
311
|
+
### Step 3c — Verify the trace chain (human, on demand)
|
|
312
|
+
|
|
313
|
+
The CSV ingests in Step 2 created two parallel trace chains. Both converge at a requirement, drill into design specs, and finally terminate at **code** and **tests** — the complete QMS traceability an auditor expects:
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
Chain A: UN ─┐
|
|
317
|
+
├─> REQ ──> DDS ──┬─> codebase (via `implemented-in`)
|
|
318
|
+
Chain B: RMA ┘ └─> tests (via `verified-by`)
|
|
263
319
|
```
|
|
264
320
|
|
|
265
|
-
|
|
321
|
+
Each arrow is a trace-link relationship type (`implemented-by`, `mitigated-by`, `detailed-in`, `implemented-in`, `verified-by`). The DDS→codebase link is stored as a frontmatter field on each DDS page (e.g. a git URL pointing at the implementing module). The DDS→tests link is a standard trace relationship added either by CSV ingest or by `mneme trace add`.
|
|
322
|
+
|
|
323
|
+
Walk either chain from any root page:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
# Chain A — from a user need forward to the specs that implement it
|
|
327
|
+
mneme trace show parkiwatch/un-001
|
|
328
|
+
# → UN.001 (secure sign-in)
|
|
329
|
+
# implemented-by -> REQ.SYS.001 (User Authentication)
|
|
330
|
+
# detailed-in -> DDS.CYB.001 (Strong Password Policy)
|
|
331
|
+
# detailed-in -> DDS.CYB.002 (Multi-Factor Authentication)
|
|
332
|
+
# ...
|
|
333
|
+
|
|
334
|
+
# Chain B — from a hazard forward to the specs that mitigate it
|
|
335
|
+
mneme trace show parkiwatch/rma-cyb-002
|
|
336
|
+
# → RMA.CYB.002 (Unauthorized access -- weak passwords)
|
|
337
|
+
# mitigated-by -> REQ.SYS.001 (User Authentication)
|
|
338
|
+
# detailed-in -> DDS.CYB.001, DDS.CYB.002, ...
|
|
339
|
+
# implemented-in -> src/auth/password_policy.py (codebase)
|
|
340
|
+
# verified-by -> TEST.AUTH.001 (tests)
|
|
341
|
+
|
|
342
|
+
# Trace gaps for a notified body audit
|
|
343
|
+
mneme trace gaps parkiwatch
|
|
344
|
+
# → Hazards with no mitigation: ...
|
|
345
|
+
# User needs with no requirements: ...
|
|
346
|
+
|
|
347
|
+
# Export the full traceability matrix for the DHF
|
|
348
|
+
mneme trace matrix parkiwatch --csv --out trace-matrix.csv
|
|
349
|
+
```
|
|
266
350
|
|
|
267
351
|
### Step 4 — Search the knowledge base (anyone)
|
|
268
352
|
|