Skip to main content
@obversa/memory-git keeps memory files in a private Git reference, so they outlive the process and never land in the working tree, and it can write a stage’s reasoning into the body of the commit that carries the stage’s change. Use it when memory must survive a restart, and when a later reader should find why a change was made on the change itself. The idea is on Memory.

Install

Included in @obversa/obversa.

Requirements

  • Git installed, on your PATH.
  • A Git repository to hold the reference.

Quickstart

Open memory over a repository, write a note and read it back:
examples/memory-git.ts (excerpt)
Each scope lives in a private reference under refs/obversa/memory/v1; the current branch, the index and the worktree are untouched. The adapter supports all six commands of the memory port: view, create, str_replace, insert, delete and rename. Run the whole file with npx tsx memory-git.ts; it creates a temporary repository and removes it:
Output

Record the reasoning

openReasoningRecord puts why a stage changed something into the commit that carries the change. It makes no commit of its own: a stage that opts in already runs in its own worktree through isolated(), and its work is committed there before it merges back. The record watches the stage while it works and, when there’s something to commit, supplies that commit’s message:
examples/reasoning-record.ts (excerpt)
compose receives the turns captured while the stage worked and returns the commit’s subject and body. Capturing as it goes keeps the discarded attempts, the part a later reader can’t reconstruct from a summary written afterwards. If compose throws or returns nothing usable, the record builds the message from the stage’s outcome instead, so a change never lands with a body that explains nothing. Opting in takes two steps: pass the record to the stage, and pass the run’s events to record.observe:
examples/reasoning-record.ts (excerpt)
The stage option names the stage. The record waits for the first turn whose path carries that name and binds to the path up to it; from then on it takes only turns under that path, so a sibling or a same-named stage elsewhere is left out. Pass path to bind the record before it sees anything. A stage that changed nothing makes no commit, so it gets no body. Run npx tsx reasoning-record.ts to see the reasoning read back from the commit:
Output

Options

openGitMemory

openReasoningRecord

Errors

  • The port’s error codes, listed on Memory port.
  • Deletion isn’t secure erasure. Delete and eviction remove a path from the private reference, but the older Git object can stay until Git removes unused objects, and mirror clones, mirror pushes and --all bundles copy the reference and its plain-text contents. Don’t treat the reference as local-only.

API

  • openGitMemory(options): a Memory over a private Git reference. Quickstart.
  • openReasoningRecord(options): a ReasoningRecorder for isolated(). Record the reasoning.
  • Types: GitMemoryOptions, ReasoningRecordOptions, ComposeInput, CapturedTurn.

Next steps

  • Memory adapters: the three adapters side by side.
  • Memory: why a commit body is the right place for the why.