Skip to main content

memory-literary-analysis

Analyze a complete literary work into a structured Basic Memory knowledge graph: schema design, entity seeding, chapter-by-chapter processing, cross-referencing, and validation.

Source facts

Repository
basicmachines-co/basic-memory
Last source activity
October 29, 2026 at 00:59
Detected SKILL.md language
English
Stars
4,391
Forks
343

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
memory-literary-analysis
description
Analyze a complete literary work into a structured Basic Memory knowledge graph: schema design, entity seeding, chapter-by-chapter processing, cross-referencing, and validation.
# Memory Literary Analysis Transform a complete literary work into a structured knowledge graph. Characters, themes, chapters, locations, symbols, and literary devices become interconnected notes — searchable, validatable, and traversable. ## Project scope If the project is unknown, discover it with `bm_project(command="list")`. Pass a nonempty `project` on every note, folder, context and schema call, even with one project or a qualified `memory://` URL. Use the chosen project's name, `workspace/project`, or external ID; `<work-name>` below is a placeholder for it. Recent activity also requires `project`. Search accepts `project` for one project, `projects` for selected projects, or `all_projects=True` explicitly. Discovery and bundled manuals need no project. Keep the same scope when following returned paths, paginating, or recovering from a refusal. ## When to Use - Analyzing a novel, play, poem, or non-fiction book end-to-end - Building a teaching or study resource for a literary text - Creating a book club companion knowledge base - Research projects requiring structured close reading - Stress-testing Basic Memory at scale (~200+ notes, 1000+ relations) ## Pipeline Overview ``` Phase 0: Setup → project, schemas, directory structure Phase 1: Seed → stub notes for known major entities Phase 2: Process → chapter-by-chapter notes in batches Phase 3: Cross-ref → enrich arcs, add parallels, write analysis Phase 4: Validate → schema checks, drift detection, consistency Phase 5: Explore → traverse the graph, write synthesis notes ``` ## Tools Writing goes through `bm_write` and `bm_edit`. MCP reads use `bm_read`, `bm_find`, `bm_search`, and `bm_list`. The CLI keeps its POSIX verbs; the table and shell examples below are CLI commands (prefix each verb with `bm`): | Need | Use | Instead of | |------|-----|-----------| | A section of a long note | `cat <note> --section Observations` | reading the whole note | | A line range of the source text | `cat <source>.txt --lines 4200-4890` | pulling the whole book into context | | Notes matching frontmatter | `find --meta status=active` | reading notes to check fields | | Fields across many notes | `find --meta ... --fields pov,setting` | one read per note | | Where something lives | `ls`, `tree`, `find --name '*.md'` | listing everything | The two rules that matter across a 100+ chapter run: - **Never read a note to check a field.** That is what `--meta` predicates and `--fields` projection are for — one call answers what a read-per-note loop would cost. - **Never pull a whole file into context to reach one part of it.** Sections and line ranges slice the *output*: the full note is still fetched, then cut down before it is returned. What they save is context, not I/O — a long chapter or a full source text costs you the tokens of the relevant part, not of the whole file. Two sharp edges to know before you write a query. The first fails *quietly* — a short answer, exit 0, no warning — so learn it here rather than from a graph you thought you had audited: - **`find` pages, and the default page is 10.** Any query whose answer is "all N chapters" needs `--page-size 100` (the maximum) and paging — see [Coverage Checks](#coverage-checks). - **`--name` cannot combine with `--meta`.** The metadata search has no filename glob. Scope a `--meta` query with the positional path instead: `find /characters --meta 'note_type=character'`. That path is matched on a directory boundary against the *file path* a note is indexed under — where the note actually lives, not its permalink, which stops mirroring the file path once a note pins `permalink:` in frontmatter or is moved. So `/characters` reaches everything filed under `characters/` (including `characters/major/`), and never `characters-cut/`. For MCP, use `bm_read(identifier="<note>", section="Observations", project="<work-name>")` or `start_line`/`end_line` for slices. Use `bm_find(filters={"type": "chapter"}, fields=["chapter_number", "pov"], project="<work-name>")` for metadata and `bm_search(query="doubloon", lines=2, project="<work-name>")` for matching lines. `bm_list` lists one folder level; `bm_find` recurses. MCP list/find/search pages cap at 100; follow `has_more` through every page. CLI page sizes and flags below are separate from the MCP shapes. ## Phase 0: Setup ### Create the Project ```python bm_project(command="create", name="<work-name>", path="~/basic-memory/<work-name>") ``` Use a kebab-case slug of the work's title (e.g., `great-gatsby`, `hamlet`, `beloved`). ### Define Schemas Write 6 schema notes to `schema/`. Each schema defines the entity type's fields, observation categories, and relation types. Adapt fields to fit the work — the schemas below are starting points, not rigid templates. #### Character Schema ```python bm_write( title="Character", directory="schema", note_type="schema", metadata={ "entity": "Character", "version": 1, "schema": { "role(enum)": "[protagonist, antagonist, supporting, minor], character's narrative role", "description": "string, brief character description", "first_appearance?": "string, chapter or scene of first appearance", "status?(enum)": "[alive, dead, unknown, transformed], character status at end of work" }, "settings": {"validation": "warn"} }, content="""# Character Schema for character entity notes. ## Observations - [convention] Major characters in characters/major/, minor in characters/minor/ - [convention] Observation categories: trait, motivation, arc, quote, appearance, relationship, symbolism, fate - [convention] Relations: appears_in, contrasts_with, allied_with, commands, symbolizes, associated_with""", project="<work-name>", ) ``` Add work-specific fields as needed — e.g., `rank` for military fiction, `house` for family sagas, `species` for fantasy. #### Theme Schema ```python bm_write( title="Theme", directory="schema", note_type="schema", metadata={ "entity": "Theme", "version": 1, "schema": { "description": "string, what this theme explores", "prevalence(enum)": "[major, minor], how central to the work", "first_introduced?": "string, where theme first appears" }, "settings": {"validation": "warn"} }, content="""# Theme Schema for thematic analysis notes. ## Observations - [convention] Observation categories: definition, manifestation, evolution, counterpoint, quote, interpretation - [convention] Relations: embodied_by, contrasts_with, reinforced_by, explored_in, expressed_through""", project="<work-name>", ) ``` #### Chapter Schema ```python bm_write( title="Chapter", directory="schema", note_type="schema", metadata={ "entity": "Chapter", "version": 1, "schema": { "chapter_number": "integer, sequential chapter number", "pov?": "string, point-of-view character or narrator mode", "setting?": "string, primary location", "narrative_mode?(enum)": "[dramatic, expository, reflective, epistolary, mixed], chapter's primary mode" }, "settings": {"validation": "warn"} }, content="""# Chapter Schema for chapter-level analysis notes. ## Observations - [convention] Chapters stored in chapters/ directory - [convention] Observation categories: summary, event, tone, technique, quote, significance, foreshadowing - [convention] Relations: features, set_in, explores, contains, employs, follows, precedes, parallels""", project="<work-name>", ) ``` #### Location Schema ```python bm_write( title="Location", directory="schema", note_type="schema", metadata={ "entity": "Location", "version": 1, "schema": { "description": "string, what this place is", "location_type(enum)": "[city, building, landscape, body_of_water, region, fictional, vehicle], type of place", "real_or_fictional(enum)": "[real, fictional, both], whether the place exists" }, "settings": {"validation": "warn"} }, content="""# Location Schema for location and setting notes. ## Observations - [convention] Observation categories: description, atmosphere, symbolism, significance, geography - [convention] Relations: setting_for, associated_with, symbolizes, contains, part_of""", project="<work-name>", ) ``` #### Symbol Schema ```python bm_write( title="Symbol", directory="schema", note_type="schema", metadata={ "entity": "Symbol", "version": 1, "schema": { "description": "string, what the symbol is literally", "symbol_type(enum)": "[object, animal, color, action, natural_phenomenon, body_part], category of symbol", "primary_meaning": "string, most common interpretation" }, "settings": {"validation": "warn"} }, content="""# Symbol Schema for symbolic element notes. ## Observations - [convention] Observation categories: meaning, appearance, ambiguity, interpretation, quote, evolution - [convention] Relations: represents, associated_with, appears_in, contrasts_with, located_at""", project="<work-name>", ) ``` #### LiteraryDevice Schema ```python bm_write( title="LiteraryDevice", directory="schema", note_type="schema", metadata={ "entity": "LiteraryDevice", "version": 1, "schema": { "description": "string, what the device is", "device_type(enum)": "[rhetorical, structural, figurative, narrative, dramatic], category", "frequency(enum)": "[pervasive, frequent, occasional, rare], how often used" }, "settings": {"validation": "warn"} }, content="""# LiteraryDevice Schema for literary technique and device notes. ## Observations - [convention] Observation categories: definition, usage, effect, example, significance - [convention] Relations: used_in, characterizes, expresses, related_to""", project="<work-name>", ) ``` ### Directory Structure ``` <project>/ <work>.txt # the source text, verbatim (see Phase 2) schema/ # 6 schema definitions chapters/ # one note per chapter/section + prologue/epilogue characters/ major/ # protagonist, antagonist, key supporting minor/ # named characters with limited roles themes/ # thematic analysis notes locations/ # settings and places symbols/ # symbolic elements literary-devices/ # techniques and devices analysis/ # cross-cutting synthesis tasks/ # processing tracker ``` ## Phase 1: Seed Entities Before processing chapters, create stub notes for major entities so `[[wiki-links]]` resolve from the start. ### Characters (major) For each major character, create a stub with known metadata: ```python bm_write( title="<Character Name>", directory="characters/major", note_type="Character", tags=["character", "major", "<role>"], metadata={"role": "<role>", "description": "<brief description>"}, content="""# <Character Name> ## Observations - [role] <Character's role in the work> - [appearance] <Key physical description> ## Relations - associated_with [[<Related Character>]] - appears_in [[<Key Location>]]""", project="<work-name>", ) ``` ### Seed Checklist Identify the work's major entities before you start reading. A good starting inventory: | Type | Typical Count | What to Include | |------|--------------|-----------------| | Characters (major) | 8-20 | Protagonist, antagonist, key supporting cast | | Themes | 5-12 | Central concerns the work explores | | Locations | 4-10 | Primary settings, symbolically significant places | | Symbols | 4-10 | Recurring objects, images, or motifs with layered meaning | Stubs don't need to be complete — they give `[[wiki-link]]` targets and will be enriched during chapter processing. ## Phase 2: Chapter Processing ### Source Text Preparation Obtain the full text and identify chapter/section boundaries. For public domain works, Project Gutenberg is a good source. For copyrighted works, work from a physical or licensed digital copy. **Put the source text inside the project directory, as `.txt`, and index it once.** `bm cat` resolves a *note identifier*, not a filesystem path — it can only reach a file the project index has observed. A one-time index pass gives the raw text an entity row, after which the line-range slice works against it: ```bash cp ~/Downloads/moby-dick.txt ~/basic-memory/moby-dick/moby-dick.txt bm reindex --search -p moby-dick # one pass; the .txt becomes readable ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub