Read ~/notes/projects/lifelog/session-plans-v3-comprehensive.md and
~/notes/projects/lifelog/all-issues-complete-inventory.md before starting
implementation work. These contain research, red-team findings, and prioritized tasks.
Nix is required. All cargo commands must run inside nix develop.
Use just recipes (which wrap nix) instead of raw cargo.
Worktrees: Feature branches use git worktrees.
- Standard Location:
worktrees/feature/<branch-name>(ignored by git). - Alternative:
~/.config/superpowers/worktrees/lifelog/(legacy/external).
| Command | What it does |
|---|---|
just work |
Display developer dashboard & active agents |
just status-all |
List all active worktrees & branch status |
just init-session |
Prepare workspace for new AI session |
just worktree-create <name> |
Create a new feature branch and local worktree |
just worktree-remove <name> |
Safely remove a worktree and its branch |
just ship-feature <name> |
Validate, merge, and prune a feature worktree |
just check |
cargo check --all-targets |
just test |
cargo test --all-targets |
just test-e2e |
Integration suite (needs PostgreSQL running) |
just validate |
Full gate: fmt + check + clippy + test |
just run-server |
Start the lifelog server |
just run-collector |
Start the collector daemon |
Proto-first: .proto files are the single source of truth for Config, State,
and DataModality types. Rust types generated via prost/tonic-build.
Unified Trait Model: DataType and Modality provide basic identity.
Unified Frames Table: All data modalities are stored in a single frames
table in PostgreSQL. Modality-specific fields go in a payload JSONB column.
Binary data is stored in a content-addressable store (CAS) referenced by blob_hash.
Catalog System: Explicit catalog table in PostgreSQL tracks registered
origins.
See @README.md for project overview.
- Commit style:
type: short description(feat/fix/refactor/docs/tests/build) - Config over env vars: All configuration comes from lifelog-config.toml. Env vars are optional overrides only.
- Privacy tiers: Modalities have tiers — sensitive (keystrokes, audio, clipboard), moderate (screenshots, browser), low (weather, processes). Respect per-tier policies in transforms and export.
- Network egress: Default local-only. External hosts must be explicitly allowlisted in config.
- Error handling: Unified
LifelogErrorinlifelog-core.thiserrorin libraries,anyhowonly in binary crates. - Testing:
just test: Unit tests.just test-e2e: Comprehensive integration suite.server/tests/ocr_pipeline.rs: End-to-end transformation test.server/tests/cross_modal_query.rs: Unified search verification.server/tests/performance_suite.rs: Throughput and latency baselines.
- Session End: At the end of the session, commit, push, and merge your changes into main.
- Update: At the end of the session, update all documents that need to be updated, this means checking out things on TODOLISTS, removing temporary files you made. Lets keep the repository up-to-date, clean, and tidy.
- NEVER run raw
cargowithout nix — native deps won't resolve - Don't touch proto files unless required — changes cascade to every crate
- Don't add env var reads — use config file; env vars are overrides only
- Don't push current git history publicly — fresh repo planned; current history contains personal data
- Don't
unwrap()in library code — use?or typed errors - Don't add interface/src-tauri to default-members — breaks CI
- Don't use
unsafe— existing unsafe is legacy debt - Don't commit broken code —
just validatebefore every commit - Build.rs
println!("cargo:...")is a Cargo directive — never replace these - Never
git add .— stage only the specific files you intend to commit - Never force push — if push fails, investigate; never use
--force - No silent failures — if an operation fails, surface an error or prominent warning; never silently fall back
- No comments in code — unless the code is complex or the user asks; mimic the file's existing style
- Check library availability — before using a crate or library, verify it's already in
Cargo.toml; never assume
- No secrets in commits — never commit API keys, tokens, or credentials
- API keys via environment variables — if a task needs an external API key, tell the user to set it as an env var; never hardcode
- Build in meaningful logging so program state, events, and errors are easy to follow for both humans and automated review.
- Mimic existing style — before editing a file, understand its conventions (naming, error handling, imports) and match them.
- Validate after changes — after making a change, run
just validate(or write a targeted test) to confirm correctness before finishing.
proto/*.proto— cascades to all cratesCargo.toml/Cargo.lock— workspace-wideserver/src/server.rs— central server logic
For coding agents (Claude Code, Gemini CLI, etc.), the repo includes a small context surface and output digests to reduce token usage. You MUST use these tools to prevent context bloat:
-
IS_LLM_AGENT(Env Var)- Effect: When set to
1(default for new agents),just check,just test, andjust validateautomatically use the digest tools below.just init-sessionalso skips the mandatory build check to speed up startup. - Toggle: Run
export IS_LLM_AGENT=0to disable and get full verbose output.
- Effect: When set to
-
tools/ai/run_and_digest.sh "<command>"...- Why: Commands like
cargo buildornpm run devoutput hundreds of lines of noise, blowing up your context window and causing you to forget previous instructions. - When: Use this whenever you need to compile code, run a test suite, or start a server where you only care about the final status or the actual errors.
- How:
tools/ai/run_and_digest.sh "cargo build"ortools/ai/run_and_digest.sh "npm install".
- Why: Commands like
-
just diff-digest- Why: Raw
git diffincludes unmodified context lines, import statements, and other boilerplate that wastes tokens. - When: Use this before committing or when reviewing what changes you've made in your current branch.
- How: Just run
just diff-digest.
- Why: Raw
-
just summary <file>- Why: Reading a 1000-line file just to find the name of a struct or a function signature is highly inefficient.
- When: Use this when exploring a new part of the codebase to get a "map" of a file's public API without reading its implementation details.
- How:
just summary server/src/query/planner.rs.
-
just check-digest- Why: Standard type checkers produce verbose output. This script distills it down to just the actionable error messages.
- When: Run this frequently during development to ensure you haven't broken the build, especially after making surgical changes.
- How: Just run
just check-digest.
-
tools/ai/scope_changes.sh <symbol>- Why: Changing a core symbol requires knowing every usage site to avoid regressions.
- When: Before refactoring or changing a public struct/function.
- How:
tools/ai/scope_changes.sh "DataModality".
-
tools/ai/bulk_replace.sh <old> <new>- Why: Replacing a string in 50 files manually blows up the context window.
- When: For large-scale renaming or refactoring.
- How:
tools/ai/bulk_replace.sh "OldType" "NewType".
-
tools/ai/summarize_output.sh- Why: Long-running servers or noisy logs flood the context.
- When: When monitoring a process that outputs repetitive lines.
- How:
npm run dev | tools/ai/summarize_output.sh.
-
rginstead ofgrep- Always use
rginstead ofgrep, you will always have access to it and it will significantly improve your efficiency. Only usegrepif you first triedrgand it failed.
- Always use
When compacting, always preserve:
- List of all modified files in this session
- Current task list and their status
- Any test commands run and their results
- Specific error messages being debugged
- One logical task per session.
/clearbetween unrelated tasks. - Use
/renameto name sessions descriptively for--resume.