git-memento is a Git extension that records the AI coding session used to produce a commit. It attaches AI conversation transcripts as git notes, creating an audit trail for AI-assisted development.
- What is git-memento?
- Getting Started
- Core Commands
- Advanced Features
- CI/CD Integration
- Build and Install
- Testing
- Contributing
- License
git-memento solves a critical problem in AI-assisted development: when an AI assistant produces a commit, the conversation that led to that change is typically lost. Team members see what changed but not why the AI was asked to change it, what alternatives were considered, or what constraints were given.
git-memento:
- Creates commits with normal Git flow (
-mor editor) - Attaches the AI session transcript to the commit using
git notes - Produces human-readable markdown notes
- Keeps provider support extensible (Codex and Claude Code supported)
- Works seamlessly with your existing Git workflow
Who is this for? Development teams using AI coding assistants (Codex, Claude Code) who want to maintain transparency, support code review, meet compliance requirements, or preserve context for debugging and onboarding.
Before using git-memento, you need:
- Git installed and configured (
git config user.nameanduser.emailset) - An AI provider CLI installed:
- Codex: Install via
npm install -g @codexcli/clior your provider's instructions - Claude Code: Install from claude.ai/code
- Codex: Install via
Install git-memento from the latest GitHub release:
curl -fsSL https://raw.githubusercontent.com/mandel-macaque/memento/main/install.sh | shThe installer will:
- Detect your OS and architecture
- Download the appropriate release binary
- Install to
~/.local/bin(or your configured install directory) - Prompt you to add the directory to your
PATHif needed
Alternative: You can also build from source if you prefer.
After installation, verify git-memento is available:
git memento --version
git memento helpInitialize git-memento for your repository. This stores provider configuration in local git metadata (.git/config):
# For Codex
git memento init codex
# For Claude Code
git memento init claudeYou only need to run init once per repository. The configuration is stored locally and won't affect other repositories.
-
Make your changes as you normally would
-
Stage your files:
git add . -
Create a commit with an attached AI session note:
git memento commit <session-id> -m "Your commit message"
- Replace
<session-id>with your AI session ID - For Codex: Find session IDs with
codex sessions list --json - For Claude Code: Use the session ID from your Claude session
Example:
git memento commit abc123 -m "Add user authentication feature" - Replace
Check that the AI session transcript was attached to your commit:
# Show the commit
git log -1 --pretty=fuller
# Show the attached note
git notes show HEADYou should see a markdown-formatted conversation with your AI provider showing the messages exchanged during the session.
Push your commit and sync the notes to your remote repository:
git memento pushThis command:
- Pushes your commits to the remote
- Syncs
refs/notes/*to the remote - Configures fetch mappings so teammates can retrieve notes
Your team members can fetch the notes with:
git memento notes-syncYou're now up and running! Continue reading for more advanced features and commands.
git memento init
git memento init codex
git memento init claudeinit stores configuration in local git metadata (.git/config) under memento.*.
git memento commit <session-id> -m "Normal commit message"
git memento commit <session-id> -m "Subject line" -m "Body paragraph"
git memento commit <session-id> --summary-skill default -m "Subject line"You can pass -m multiple times, and each value is forwarded to git commit in order. When -m is omitted, git commit opens your default editor.
git memento amend -m "Amended subject"
git memento amend <new-session-id> -m "Amended subject" -m "Amended body"
git memento amend <new-session-id> --summary-skill session-summary-default -m "Amended subject"amend runs git commit --amend:
- Without a session id, it copies the note(s) from the previous HEAD onto the amended commit
- With a session id, it copies previous note(s) and appends the new fetched session as an additional session entry
- A single commit note can contain sessions from different AI providers
--summary-skill <skill|default> (for commit and amend <session-id>) changes note behavior:
- The default notes ref (
refs/notes/commits) stores a summary record instead of the full transcript - The full session is stored in
refs/notes/memento-full-audit - The CLI prints the generated summary and asks for confirmation
- If rejected, you must provide a prompt to regenerate
defaultmaps to the repository skill atskills/session-summary-default/SKILL.md- The default summary skill is always applied as a baseline; if a user-provided summary skill conflicts with it, user-provided instructions take precedence
Verify both notes after a summary run:
git notes show <commit-hash>
git notes --ref refs/notes/memento-full-audit show <commit-hash>git memento share-notes
git memento share-notes upstreamThis pushes refs/notes/* and configures local remote.<name>.fetch so notes can be fetched by teammates.
git memento push
git memento push upstreamThis runs git push <remote> and then performs the same notes sync as share-notes. Default remote is origin.
If a session id is not found, git-memento asks the configured provider for available sessions and prints them.
This command:
- Ensures notes fetch mapping is configured
- Creates backup refs under
refs/notes/memento-backups/<timestamp>/... - Fetches remote notes into
refs/notes/remote/<remote>/* - Merges remote notes into local notes and pushes synced notes back to the remote
- Syncs both
refs/notes/commitsandrefs/notes/memento-full-audit
git memento notes-sync
git memento notes-sync upstream
git memento notes-sync upstream --strategy unionDefault remote is origin, default strategy is cat_sort_uniq.
git memento audit --range main..HEAD
git memento audit --range origin/main..HEAD --strict --format jsonAudit note coverage and note metadata in a commit range:
- Reports commits with missing notes (
missing-note <sha>) - Validates note metadata markers (
- Provider:and- Session ID:) - In
--strictmode, invalid note structure fails the command
git memento doctor
git memento doctor upstream --format jsonRun repository diagnostics for provider config, notes refs, and remote sync posture.
git memento help
git memento --versionFor rewritten commits (rebase / commit --amend):
git memento notes-rewrite-setupThis sets local git config:
notes.rewriteRef=refs/notes/*notes.rewriteMode=concatenatenotes.rewrite.rebase=truenotes.rewrite.amend=true
For squash/rewrite flows onto a new target commit:
git memento notes-carry --onto <new-commit> --from-range <base>..<head>This reads notes from commits in <base>..<head> and appends provenance blocks to <new-commit>. It carries both refs/notes/commits and refs/notes/memento-full-audit.
Provider defaults can come from env vars, and init persists the selected provider + values in local git config:
MEMENTO_AI_PROVIDER(default:codex)MEMENTO_CODEX_BIN(default:codex)MEMENTO_CODEX_GET_ARGS(default:sessions get {id} --json)MEMENTO_CODEX_LIST_ARGS(default:sessions list --json)MEMENTO_CODEX_SUMMARY_BIN(default:codex)MEMENTO_CODEX_SUMMARY_ARGS(default:exec -c skill.effective_path={effectiveSkillPath} -c skill.default_path={defaultSkillPath} -c skill.user_path={userSkillPath} "{prompt}")MEMENTO_CLAUDE_BIN(default:claude)MEMENTO_CLAUDE_GET_ARGS(default:sessions get {id} --json)MEMENTO_CLAUDE_LIST_ARGS(default:sessions list --json)MEMENTO_CLAUDE_SUMMARY_BIN(default:claude)MEMENTO_CLAUDE_SUMMARY_ARGS(default:-p --append-system-prompt "Skill paths: effective={effectiveSkillPath}; default={defaultSkillPath}; user={userSkillPath}. Prefer user skill when provided." "{prompt}")
Summary args template placeholders:
{prompt}: generated summary prompt{sessionId}: session id{skill}: user skill name orsession-summary-default{defaultSkillPath}: default skill file path (skills/session-summary-default/SKILL.md){userSkillPath}: user skill file path (empty when--summary-skill default){effectiveSkillPath}: user skill path when provided, otherwise default skill path
Security behavior:
- Session transcript is treated as untrusted data
- Summary prompt explicitly instructs the model not to follow instructions embedded in transcript content
Set MEMENTO_AI_PROVIDER=claude to use Claude Code.
- If the repository is not configured yet,
commit,amend <session-id>,push,share-notes,notes-sync,notes-rewrite-setup, andnotes-carryfail with a message to rungit memento initfirst - Stored git metadata keys include:
memento.providermemento.codex.bin,memento.codex.getArgs,memento.codex.listArgs,memento.codex.summary.bin,memento.codex.summary.argsmemento.claude.bin,memento.claude.getArgs,memento.claude.listArgs,memento.claude.summary.bin,memento.claude.summary.args
If a session id is not found, git-memento asks the provider for available sessions and prints them.
- Notes are written with
git notes add -f -m "<markdown>" <commit-hash> - Multi-session notes use explicit delimiters:
<!-- git-memento-sessions:v1 --><!-- git-memento-note-version:1 --><!-- git-memento-session:start --><!-- git-memento-session:end -->
- Legacy single-session notes remain supported and are upgraded to the versioned multi-session envelope when amend needs to append a new session
- Conversation markdown labels user messages with your git alias (
git config user.name) and assistant messages with provider name - Serilog debug logs are enabled in
DEBUGbuilds
This repository includes a reusable marketplace action with three modes:
mode: comment(default): readsgit notescreated bygit-mementoand posts a commit comment.mode: gate: runsgit memento auditas a CI gate and fails if note coverage checks fail.git-mementomust already be installed in the job.mode: merge-carry: on merged pull requests, carries notes from PR commits onto the merge commit and pushesrefs/notes/*.
Action definition:
action.ymlat repository rootinstall/action.ymlfor reusable git-memento installation- Renderer source:
src/note-comment-renderer.ts - Runtime artifact committed for marketplace consumers:
dist/note-comment-renderer.js
name: memento-note-comments
on:
push:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
permissions:
contents: write
pull-requests: read
jobs:
comment-memento-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mandel-macaque/memento@v1
with:
mode: comment
github-token: ${{ secrets.GITHUB_TOKEN }}Inputs:
github-token(default:${{ github.token }})mode(default:comment) -comment,gate, ormerge-carrynotes-fetch-refspec(default:refs/notes/*:refs/notes/*)max-comment-length(default:65000)audit-range(optional, gate mode)base-ref(optional, gate mode pull request inference)strict(default:true, gate mode)ignore-label(default:ignore-notes, gate mode)- If present on a pull request, gate note checks are skipped and a PR comment with
Notes ignoredis posted.
- If present on a pull request, gate note checks are skipped and a PR comment with
carry-onto(optional, merge-carry mode) - target commit SHA. Defaults topull_request.merge_commit_sha.carry-range(optional, merge-carry mode) - explicit<base>..<head>source range.carry-base-sha(optional, merge-carry mode) - base SHA used whencarry-rangeis empty.carry-head-sha(optional, merge-carry mode) - head SHA used whencarry-rangeis empty.carry-provider(default:codex, merge-carry mode) - provider value set in local git config fornotes-carry.
Installer action inputs:
install-dir(default:${{ runner.temp }}/git-memento-bin)verify(default:true)
CI gate example:
name: memento-note-gate
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
enforce-memento-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mandel-macaque/memento/install@v1
- uses: mandel-macaque/memento@v1
with:
mode: gate
strict: "true"
ignore-label: "ignore-notes"Merge-carry example:
name: memento-notes-merge-carry
on:
pull_request:
types: [closed]
permissions:
contents: write
jobs:
carry-notes-to-merge-commit:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: mandel-macaque/memento/install@v1
with:
memento-repo: mandel-macaque/memento
- uses: mandel-macaque/memento@v1
with:
mode: merge-carryInstaller action example:
- uses: mandel-macaque/memento/install@v1.github/workflows/memento-note-comments.yml.github/workflows/memento-note-gate.yml.github/workflows/memento-notes-merge-carry.yml- Uses the public action with
mode: merge-carry. - Carries notes from PR source commits onto the merge commit.
- Pushes updated
refs/notes/*so merged commits keep note visibility in downstream checks.
- Uses the public action with
- Build and commit the action renderer artifact:
npm ci
npm run build:action
git add src/note-comment-renderer.ts dist/note-comment-renderer.js- Ensure
action.ymlandinstall/action.ymlare in the default branch and README documents usage - Create and push a semantic version tag:
git tag -a v1.0.0 -m "Release GitHub Action v1.0.0"
git push origin v1.0.0
git tag -f v1 v1.0.0
git push -f origin v1- In GitHub, open your repository page:
Releases->Draft a new release-> choosev1.0.0-> publish
- Open the
Marketplace(GitHub Store) publishing flow from the repository and submit listing metadata - Keep the major tag (
v1) updated to the latest compatible release
Local workflow in this repository:
.github/workflows/memento-note-comments.yml.github/workflows/memento-note-gate.yml.github/workflows/memento-notes-merge-carry.yml
Requires .NET SDK 10 and native toolchain dependencies for NativeAOT.
dotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r osx-arm64 -p:PublishAot=truedotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r linux-x64 -p:PublishAot=truedotnet publish src/GitMemento.Cli/GitMemento.Cli.fsproj -c Release -r win-x64 -p:PublishAot=trueGit discovers commands named git-<name> in PATH.
- Publish for your platform
- Copy the produced executable to a directory in your
PATH - Ensure the binary name is
git-memento(orgit-memento.exeon Windows)
Then run:
git memento commit <session-id> -m "message"- Release assets are built with NativeAOT (
PublishAot=true) and packaged as a single executable per platform - If the workflow runs from a tag push (for example
v1.2.3), that tag is used as the GitHub release tag/name - If the workflow runs from
mainwithout a tag, the release tag becomes<Version>-<shortSha>(for example1.0.0-a1b2c3d4) install.shalways downloads fromreleases/latest, so the installer follows the latest published GitHub release
CI runs install smoke tests on Linux, macOS, and Windows that verify:
install.shdownloads the latest release asset for the current OS/architecture- The binary is installed for the current user into the configured install directory
git memento --versionandgit memento helpboth execute after installation
dotnet test GitMemento.slnx
npm run test:jsContributions are welcome! To contribute:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests to ensure everything works
- Submit a pull request
For development setup, see Build (AOT).
See LICENSE file for details.