📝 MEMSTORE_MANUAL.mdv4.6.0 · 2026-10-19

memstore.py — Manual

Project: Project AI Chatbot Memstore Version: 1.1.0 Date: 2026-10-26 Another collaboration between Andrew.human and Claude.ai

Written to be read by people and by AI models.

What it is

A small personal memory store in one Python file, backed by one SQLite file. It holds short statements about the operator (one entry per statement), each with the quote it came from. It runs without any language model on the machine.

The rule it enforces: nothing becomes live memory unless the operator adds it or approves it. Only approved entries are ever printed by inject.

A separate program, qwen_propose.py (see QWEN_PROPOSE_MANUAL.md), can suggest entries using a local model. It never touches this database.

Requirements

Upgrading from 1.0.0

Copy the new memstore.py over the old one and run any command. The first run adds three columns (kind, importance, superseded_by) to your existing database automatically. Existing entries become kind fact, importance 2. Back up memstore.db first if you want a way back; the 1.0.0 program cannot read a migrated database's new columns but will still open it.

Database file

Default /root/memstore/memstore.db (the folder comes from $MEMDIR if set), whatever folder you run the command from. Override with --db PATH or the environment variable MEMSTORE_DB. Created on first run. The path in use prints to stderr on every run.

Each entry holds:

Field Meaning
id Entry number
text The statement, short, third person preferred ("Operator prefers X")
quote The original words it came from
source_id Which transcript or conversation it came from (optional)
origin stated (said directly) or inferred (concluded, not said)
kind fact, or correction (always injected)
importance 1 to 3, default 2; ranks inject output
status proposed, approved, rejected or superseded
superseded_by Id of the entry that replaced this one
sensitive 1 if a sensitive keyword matched the text or the quote
created, decided UTC timestamps

Commands

Every run prints memstore 1.1.0 (2026-10-26) once to stderr at start, so inject output on stdout stays clean for piping.

Command What it does
add TEXT... [--quote Q] [--source S] [--kind fact|correction] [--importance 1-3] Explicit entry. Approved immediately, origin stated. Refused only if the same text is already proposed or approved.
supersede OLD_ID TEXT... [--quote Q] [--source S] [--kind K] [--importance N] Replace an approved entry. The new entry is approved at once. The old one is kept, marked superseded, and never injected. Kind and importance default to the old entry's.
propose FILE.json Import candidates. Status proposed. Nothing is live yet.
review Show everything awaiting approval, with quote and flags.
approve ID... [--importance N] Approve specific entries, optionally setting importance.
approve --all Approve all proposals except sensitive ones, which are listed as held back.
reject ID... Reject proposals. Kept as rejected so they are not re-proposed.
list [--status S] List entries. Each line shows id, status, importance, flags.
inject [WORDS...] [--limit N] Print approved entries as - text lines (see below).
forget --id N Delete one entry for real.
forget --source S Delete every entry that came from source S.

How inject orders its output

  1. Corrections first, as - CORRECTION: text. They are never filtered by keywords and never count against --limit.
  2. Then facts. With keywords: only facts sharing a word with the keywords, ranked by shared words, then importance, then newest. Without keywords: ranked by importance, then newest.
  3. --limit N caps the facts only.
  4. Inferred entries carry an [inferred] suffix. Superseded, rejected and proposed entries are never printed.

Superseding versus forgetting

supersede keeps history: the old text stays in the database, visible in list. forget is real deletion (the row is removed, secure_delete is on, and the file is compacted with VACUUM). Use forget when text must not remain, including old superseded entries.

Proposal file format

A JSON list. Each item:

[
{
"text": "Operator prefers short replies",
"quote": "keep it short please",
"source_id": "chat-2026-10-25-01",
"origin": "stated",
"kind": "fact",
"importance": 2
}
]

Sensitive entries

On import (and on add), an entry is flagged SENSITIVE if its text or its quote matches keywords for health, identity and belief, money and legal matters. Flagged entries are never approved by approve --all; each needs approve ID.

Limits, stated plainly:

Typical session

python3 memstore.py add "Operator prefers Markdown" --quote "Markdown only"
python3 memstore.py add "Operator requires ordered shutdowns" --kind correction --importance 3
python3 memstore.py propose proposals.json
python3 memstore.py review
python3 memstore.py approve 4 7
python3 memstore.py approve --all
python3 memstore.py supersede 3 "Operator runs CentOS 6.10" --quote "6.10"
python3 memstore.py inject markdown --limit 20
python3 memstore.py forget --source chat-2026-10-25-01

Exit codes

0 success, 1 import finished with invalid items, 2 usage or input error.

Ordered shutdown

No service or background process is involved. The program starts, runs one command and exits.

Version history

Version Date Change
1.1.1 2026-10-27 Database default is now /root/memstore/memstore.db instead of ./memstore.db; the path in use prints at start.
1.1.0 2026-10-26 Added correction kind, supersede, importance ranking, automatic migration. Fixed: rejected/superseded entries could be re-proposed; sensitive check ignored the quote; inject --limit kept the oldest entries.
1.0.0 2026-10-25 First release.