Skip to main content

Local-first long-horizon project memory for AI research

Project description

projmem

CI Python Coverage License: MIT

Local-first long-horizon project memory for AI/ML research — no account, no cloud, no telemetry.

pmem is a CLI tool that records what you did and why: which files you tracked, every command you ran, configs/metrics/artifacts from each run, Git state at the time, and failure taxonomy for experiments that went wrong. Everything lives in a local SQLite database inside .pmem/.


Why projmem?

MLflow / W&B projmem
Needs account / server
Works fully offline
Records failure taxonomy
Privacy: no remote URL stored
Secret redaction in config
Dependency footprint Heavy pydantic + rich + typer

projmem is built for researchers and engineers who want experiment memory without giving up privacy or requiring infra.


Demo

$ pmem init --objective "Train AG News baseline" --metric accuracy \
            --metric-direction max --target 0.9
✓ Initialized project 'my-experiment' in .pmem/

$ pmem track train.py
✓ Tracked train.py (sha256: a3f8c1…)

$ pmem run --name smoke --seed 42 --config config.json \
           --metrics metrics.json -- python train.py
● Running: python train.py
✓ Run completed  exit=0  run_id=r-01j…
  stdout → .pmem/artifacts/runs/r-01j…/stdout.txt
  metrics → .pmem/artifacts/runs/r-01j…/metrics.json

$ pmem run --name failed-run -- python train.py --bad-flag
✗ Run failed  exit=1  run_id=r-02j…
  stderr → .pmem/artifacts/runs/r-02j…/stderr.txt

Installation

Public PyPI install for the latest published alpha:

pip install projmem
pmem --help

TestPyPI rehearsal install for the Phase 2A alpha candidate after rehearsal publish:

pip install -i https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple \
  projmem==0.2.0a0
pmem --help

Development install from source:

# Requires uv — https://docs.astral.sh/uv/
uv sync --all-groups --no-editable
uv run --no-sync pmem --help

Commands

Command What it does
pmem init Create .pmem/ and record project goal, metric, target
pmem track <path> Hash and register a file; --update refreshes the hash
pmem run -- <cmd> Execute a command and capture stdout/stderr, Git state, exit code
pmem run --seed --config --metrics --artifact Full metadata run (D8)
pmem log-failure <run-id> <type> <description> Store a confirmed failure with D11 taxonomy; supports --output json
pmem log-decision <description> Store a durable project decision and optional rationale
pmem note <content> Store a lightweight project note
pmem baseline <run-id> Mark a run as experiment baseline; --compare compares another run
pmem summary Print project objective, target status, best run, timeline, and warnings
pmem export --json Export Phase 1 project memory as deterministic JSON
pmem export-bundle --out <path> [--json] Write a deterministic Phase 2 bundle; artifact bytes are opt-in
pmem import --dry-run <bundle> [--json] Validate a Phase 2 bundle without mutating SQLite
pmem import --apply <bundle> --confirm [--json] Quarantine a validated bundle as a pending import job
pmem conflict-check <bundle> [--json] Detect bundle conflicts before merge or destructive write
pmem resolve <conflict-id> --action <action> [--json] Record a non-destructive conflict resolution audit event
pmem share init <path> [--alias] [--json] Register an explicit local shared memory path
pmem share status [--json] Validate registered shared memory paths
pmem failures list [--json] List confirmed failures without raw free text by default
pmem failures export --out <path> [--json] Export failure records as deterministic JSON; raw text requires --include-text --confirm
pmem failures embed [--json] Compute deterministic local failure embeddings without network or vector DB
pmem failures cluster [--json] Cluster local failure embeddings and emit a deterministic 2D projection
pmem failures patterns [--json] Generate human-reviewable pattern candidates with heuristic labels
pmem failures summary [--json] Summarize failure analysis status and top pattern candidates

Architecture

pmem run -- python train.py
      │
      ▼
  cli/           ← parse args, render output         (Typer + Rich)
  services/      ← use-case orchestration, transactions
  domain/        ← entities, enums, Pydantic v2 validation
  repositories/  ← SQLite read/write (parameterized queries only)
  migrations/    ← schema versioning, backup, integrity check
  integrations/  ← Git metadata capture (best-effort, no remote URL)
  utils/         ← SHA-256 hashing, helpers

Dependency direction is strictly one-way: cli → services → domain / repositories / integrations. Domain never imports CLI, service, or migration code.

Quality

  • 300+ tests — unit + integration + security, 95%+ coverage enforced at CI
  • Matrix CI — Python 3.10 / 3.11 / 3.12 × Ubuntu 22.04 / macOS 14
  • Static analysisruff (lint + format) + pyright (strict type checking)
  • Pre-commit hooksdetect-secrets, ruff, pyright on every commit
  • Security hardening — path traversal guard, secret redaction, no remote URL stored
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest --cov=pmem --cov-report=term-missing
uv run pre-commit run --all-files

Data Model

.pmem/pmem.db — local SQLite, never leaves the machine:

Table Stores
projects name, goal, objective, metric, target
tracked_paths file path, SHA-256 hash, timestamps
experiments name, description
runs command, exit code, seed, config hash, stdout/stderr preview, Git metadata
failures confirmed failure records with severity/source/tags
decisions durable decisions with rationale
notes lightweight project notes and run/experiment links
experiments.metadata_json baseline run id and baseline metrics
export_packages Phase 2 bundle manifest/payload hash and local export audit metadata
import_jobs pending/quarantined import jobs and dry-run validation reports
shared_paths explicit local shared memory path registrations
audit_events portability and import/export audit evidence

Security & Privacy

  • All data stays local — .pmem/ is project-local by design
  • Git remote URLs are never stored
  • Config keys matching token / password / secret / key patterns are redacted before DB insert
  • Path traversal and command injection are actively guarded against
  • .pmem/ itself cannot be tracked (prevents recursive capture)

SECURITY.md for full policy.

Phase 1 alpha is complete: local CLI, SQLite persistence, run capture, failure/decision/note memory, baseline comparison, summary, export, TestPyPI rehearsal, and PyPI install smoke have all passed.

Phase 2A foundation is scoped around local-first portability and collaboration: schema portability tables, deterministic export bundles, import dry-run validation, pending/quarantined import apply, conflict detection, non-destructive resolution audit events, shared memory path registration/status, schema compatibility, evidence-bundle provenance, security/privacy hardening, and release-readiness review. See docs/roadmap/phase-2.md.

Phase 2B starts from the accepted Phase 2A contracts and focuses on privacy-safe failure analysis. pmem failures list/export provides a local substrate for later embedding, clustering, and pattern reporting. pmem failures embed/cluster/patterns/summary uses deterministic local hashing vectors, cosine-threshold clustering, and metadata-first heuristic labels by default. Pattern labels are audit candidates, not confirmed root causes. Optional heavier NLP features are gated behind local capability checks and are not part of the core runtime path.


Local-First Guarantee

All Phase 1 commands run offline and write only to .pmem/:

.pmem/
  config.yaml          ← project metadata
  pmem.db              ← SQLite database
  artifacts/runs/      ← stdout, stderr, metrics, artifact files per run
  snapshots/           ← (planned) file snapshots

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

projmem-0.2.0a0.tar.gz (84.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

projmem-0.2.0a0-py3-none-any.whl (111.8 kB view details)

Uploaded Python 3

File details

Details for the file projmem-0.2.0a0.tar.gz.

File metadata

  • Download URL: projmem-0.2.0a0.tar.gz
  • Upload date:
  • Size: 84.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for projmem-0.2.0a0.tar.gz
Algorithm Hash digest
SHA256 da45ddae3898fef7fe41091e52e3c8ee8e37fd4aba5556301b8ca0d21f8cc28f
MD5 6446d0024f73ec64056cdd69df5f7cc7
BLAKE2b-256 1d90d971308fea07eb26c489d9fe0d18eb60046d45d923a14231ca1f48236af1

See more details on using hashes here.

Provenance

The following attestation bundles were made for projmem-0.2.0a0.tar.gz:

Publisher: publish-pypi.yml on umynameislove/projmem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file projmem-0.2.0a0-py3-none-any.whl.

File metadata

  • Download URL: projmem-0.2.0a0-py3-none-any.whl
  • Upload date:
  • Size: 111.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for projmem-0.2.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdcd3da26bd4608b1323220384a42cb0041d3f9577f91b92b113b2e81d3ea5cd
MD5 e23b2d9dd26939dbecf2994d023dd006
BLAKE2b-256 e3c7f3788fff687d67fde882b7636d522612da743b617577ae78fdf0947f4ed0

See more details on using hashes here.

Provenance

The following attestation bundles were made for projmem-0.2.0a0-py3-none-any.whl:

Publisher: publish-pypi.yml on umynameislove/projmem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page