Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ jobs:
- name: Check formatting
run: cargo fmt --all -- --check

release-guards:
name: Release Guard Scripts
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Run release guard tests
run: bash scripts/release-guards-test.sh

clippy:
name: Clippy
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -232,7 +240,7 @@ jobs:
# Summary job that depends on all other jobs
ci-success:
name: CI Success
needs: [fmt, clippy, test, build, doc, e2e, benchmark-smoke]
needs: [fmt, clippy, test, build, doc, e2e, benchmark-smoke, release-guards]
runs-on: ubuntu-24.04
if: always()
steps:
Expand All @@ -244,7 +252,8 @@ jobs:
[[ "${{ needs.build.result }}" != "success" ]] || \
[[ "${{ needs.doc.result }}" != "success" ]] || \
[[ "${{ needs.e2e.result }}" != "success" ]] || \
[[ "${{ needs.benchmark-smoke.result }}" != "success" ]]; then
[[ "${{ needs.benchmark-smoke.result }}" != "success" ]] || \
[[ "${{ needs.release-guards.result }}" != "success" ]]; then
echo "One or more jobs failed"
exit 1
fi
Expand Down
122 changes: 85 additions & 37 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,62 @@ on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.2.0)'
description: 'Version to release (e.g., 3.1.0, no leading v)'
required: true
type: string
dry_run:
description: 'Run guards (and, if they pass, builds) but do not publish a GitHub Release or push a tag'
required: false
type: boolean
default: false

env:
CARGO_TERM_COLOR: always

jobs:
guard:
name: Release guards
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
tag: ${{ steps.meta.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fetch origin/main
run: git fetch --no-tags origin '+refs/heads/main:refs/remotes/origin/main'

- name: Resolve version
id: meta
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
raw="${{ github.event.inputs.version }}"
else
raw="${GITHUB_REF_NAME}"
fi
raw="${raw#v}"
echo "version=${raw}" >> "$GITHUB_OUTPUT"
echo "tag=v${raw}" >> "$GITHUB_OUTPUT"

- name: Guard tagged commit is on main and version matches Cargo.toml
run: |
bash scripts/release-guards.sh \
--version "${{ steps.meta.outputs.version }}" \
--sha "${GITHUB_SHA}" \
--main-ref origin/main \
--cargo Cargo.toml

- name: Guard CHANGELOG.md has a matching section
run: |
bash scripts/changelog-section.sh "${{ steps.meta.outputs.version }}" CHANGELOG.md \
> "$RUNNER_TEMP/release-notes.md"
test -s "$RUNNER_TEMP/release-notes.md"

build:
name: Build (${{ matrix.name }})
needs: guard
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand Down Expand Up @@ -46,16 +92,6 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Get version
id: version
shell: bash
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
fi

- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
Expand Down Expand Up @@ -123,7 +159,7 @@ jobs:
- name: Create archive directory
shell: bash
run: |
VERSION=${{ steps.version.outputs.version }}
VERSION=${{ needs.guard.outputs.version }}
ARCHIVE_DIR="agent-memory-${VERSION}-${{ matrix.name }}"
mkdir -p "dist/${ARCHIVE_DIR}"

Expand Down Expand Up @@ -152,7 +188,7 @@ jobs:
if: runner.os != 'Windows'
shell: bash
run: |
VERSION=${{ steps.version.outputs.version }}
VERSION=${{ needs.guard.outputs.version }}
ARCHIVE_DIR="agent-memory-${VERSION}-${{ matrix.name }}"
cd dist
tar -czvf "${ARCHIVE_DIR}.tar.gz" "${ARCHIVE_DIR}"
Expand All @@ -162,7 +198,7 @@ jobs:
if: runner.os == 'Windows'
shell: pwsh
run: |
$VERSION = "${{ steps.version.outputs.version }}"
$VERSION = "${{ needs.guard.outputs.version }}"
$ARCHIVE_DIR = "agent-memory-${VERSION}-${{ matrix.name }}"
cd dist
Compress-Archive -Path $ARCHIVE_DIR -DestinationPath "${ARCHIVE_DIR}.zip"
Expand All @@ -177,57 +213,69 @@ jobs:

release:
name: Create Release
needs: build
if: always() && !cancelled()
needs: [guard, build]
# success() is required: a custom `if` replaces the implicit "needed jobs
# succeeded" check. The previous `if: always() && !cancelled()` is how a
# partial set of archives could ship. dry_run skips publish after a green
# guard+build, which is the live way to verify the guards without a tag.
if: ${{ success() && (github.event_name != 'workflow_dispatch' || github.event.inputs.dry_run != 'true') }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- name: Get version
id: version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
echo "tag=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
echo "tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
fi

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: release-*
merge-multiple: true

- name: List artifacts
run: ls -laR artifacts/
- name: Require all five platform archives
run: |
ls -laR artifacts/
missing=0
for name in linux-x86_64 linux-aarch64 macos-x86_64 macos-aarch64 windows-x86_64; do
if ! ls artifacts/agent-memory-${{ needs.guard.outputs.version }}-${name}.* >/dev/null 2>&1; then
echo "::error::missing archive for ${name}"
missing=1
fi
done
if [[ "$missing" -ne 0 ]]; then
echo "Refusing to publish a partial release."
exit 1
fi

- name: Generate checksums
run: |
cd artifacts
sha256sum *.tar.gz *.zip > SHA256SUMS.txt 2>/dev/null || sha256sum *.tar.gz > SHA256SUMS.txt 2>/dev/null || echo "No artifacts to checksum"
cat SHA256SUMS.txt 2>/dev/null || true
sha256sum *.tar.gz *.zip > SHA256SUMS.txt
cat SHA256SUMS.txt

- name: Release notes from CHANGELOG.md
run: |
bash scripts/changelog-section.sh "${{ needs.guard.outputs.version }}" CHANGELOG.md \
> release-notes.md
test -s release-notes.md

- name: Create tag (workflow_dispatch only)
if: github.event_name == 'workflow_dispatch'
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git tag -a ${{ steps.version.outputs.tag }} -m "Release ${{ steps.version.outputs.tag }}"
git push origin ${{ steps.version.outputs.tag }}
git tag -a ${{ needs.guard.outputs.tag }} -m "Release ${{ needs.guard.outputs.tag }}" "${GITHUB_SHA}"
git push origin ${{ needs.guard.outputs.tag }}

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.version }}
tag_name: ${{ needs.guard.outputs.tag }}
name: Release ${{ needs.guard.outputs.version }}
draft: false
prerelease: ${{ contains(steps.version.outputs.version, '-') }}
generate_release_notes: true
prerelease: ${{ contains(needs.guard.outputs.version, '-') }}
generate_release_notes: false
body_path: release-notes.md
files: |
artifacts/*.tar.gz
artifacts/*.zip
Expand Down
18 changes: 17 additions & 1 deletion .planning/MILESTONES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# Project Milestones: Agent Memory

## v3.1 Make It True (Shipped: 2026-08-31)
## v3.2 Prove It (In progress: 2026-09-01)

**Goal:** v3.1 made the claims true; v3.2 makes them provable. A real LOCOMO
number, evidence behind every "Solid", a daemon someone can run for a week,
and a repo whose backlog is public.

**Spec:** `docs/plans/v3.2-prove-it-plan.md`

**Phases:** 59 Guardrails and Inventory (executing), 60 Real Numbers, 61
Operate It, 62 Cross-encoder rerank (conditional on #39).

**Known Gaps (now issues):** #39 LOCOMO run, #40 vector/topic quality, #41
backfill, #42 install-service, #43 TOC rebuild, #44 cross-encoder.

---

## v3.1 Make It True (Shipped: 2026-09-01)

**Delivered:** no new capabilities. Four phases closing the gap between what the
project claimed and what it did, after a v3.0 verification document self-graded
Expand Down
70 changes: 40 additions & 30 deletions .planning/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@

## Current State

**Version:** v3.0 (In Progress)
**Status:** Building retrieval orchestration, CLI API, and benchmark suite
**Version:** v3.1.0 (Shipped 2026-09-01)
**Status:** v3.2 "Prove It" in execution — make the v3.1 claims provable

## Current Milestone: v3.0 Competitive Parity & Benchmarks
## Current Milestone: v3.2 Prove It

**Goal:** Close the three gaps that keep Agent-Memory from being the category leader: retrieval pipeline orchestration, a dead-simple CLI API, and a benchmark suite that produces a publishable LOCOMO score.
**Goal:** a stranger arriving from a Show HN link finds a real LOCOMO number,
evidence behind every "Solid", a daemon they can run for a week, and a repo
that looks alive. No new capabilities. v3.1 made the claims true; v3.2 makes
them provable.

**Target features:**
- Retrieval Orchestrator crate (query expansion, RRF fusion, LLM reranking)
- Simple `memory` CLI binary (search, context, recall, add, timeline, summary)
- Benchmark suite with custom harness + LOCOMO adapter
- Positioning writeup (side quest, not a GSD phase)
**Target work:**
- Release pipeline guards (tag on main, crate version matches tag, all five platforms) — Phase 59
- Committed LOCOMO LLM-judge result on the real dataset — Phase 60 / #39
- Quality fixtures for vector search and the topic graph — Phase 60 / #40
- Backfill, `install-service`, offline TOC rebuild, panic audit — Phase 61 / #41 #42 #43
- Claude Code plugin registration + installer uninstall/status — Phase 61
- Cross-encoder rerank only if 60-02 says retrieval is the bottleneck — Phase 62 / #44

**Previous version:** v2.7 (Shipped 2026-03-22) — Multi-runtime installer with 6 converters
**Previous version:** v3.1.0 (Shipped 2026-09-01) — Make It True. No new
capabilities; closed the claim/reality gap (orchestrator reachable, hybrid
actually fuses, honest benchmarks, shop window). See
`docs/plans/v3.1-make-it-true-plan.md`.

**Spec reference:** `docs/superpowers/specs/2026-03-21-v3-competitive-parity-design.md`
**Plan references:**
- `docs/superpowers/plans/2026-03-21-v3-phase-a-retrieval-orchestrator.md`
- `docs/superpowers/plans/2026-03-21-v3-phase-b-simple-cli-api.md`
- `docs/superpowers/plans/2026-03-21-v3-phase-c-benchmark-suite.md`
**Spec reference:** `docs/plans/v3.2-prove-it-plan.md`

The system implements a complete 6-layer cognitive stack with control plane, multi-agent support, semantic dedup, retrieval quality filtering, multi-runtime installer, and comprehensive testing:
- Layer 0: Raw Events (RocksDB) — agent-tagged, dedup-aware (store-and-skip-outbox)
Expand All @@ -31,23 +35,23 @@ The system implements a complete 6-layer cognitive stack with control plane, mul
- Layer 4: Semantic Teleport (Vector/HNSW) — also used for dedup similarity checks
- Layer 5: Conceptual Discovery (Topic Graph) — agent-filtered queries
- Layer 6: Ranking Policy (salience, usage, novelty, lifecycle) + StaleFilter (time-decay, supersession)
- Control: Retrieval Policy (intent routing, tier detection, fallbacks)
- Control: Retrieval Policy (intent routing, tier detection, fallbacks) + MemoryOrchestrator (RRF fusion, optional LLM rerank, explainability)
- Dedup: InFlightBuffer + HNSW composite gate, configurable threshold, fail-open
- Installer: memory-installer crate with RuntimeConverter trait, 6 converters, tool mapping tables
- Adapters: Claude Code, OpenCode, Gemini CLI, Copilot CLI, Codex CLI (via installer)
- Installer: memory-installer crate with RuntimeConverter trait, 5 converters (Claude, Gemini, Codex, Copilot, generic skills), tool mapping tables
- Adapters: Claude Code, Gemini CLI, Copilot CLI, Codex CLI (via installer). OpenCode removed in v3.1 Phase 57 — the converter reported success and wrote nothing
- Discovery: ListAgents, GetAgentActivity, agent-filtered topics
- Testing: 46 cargo E2E tests + 144 bats CLI tests across 5 CLIs
- CI/CD: Dedicated E2E job + CLI matrix report in GitHub Actions
- Setup: Quickstart, full guide, agent setup docs + 4 wizard-style setup skills
- Benchmarks: perf_bench harness with baseline metrics across all retrieval layers
- Testing: 1,205 workspace + 60 e2e cargo tests; 114 bats CLI tests; Tier 1 (Claude Code, Codex) gates PRs, Tier 2 (Gemini, Copilot) weekly
- CI/CD: Dedicated E2E job + CLI matrix report; rust-toolchain pinned to 1.97
- Setup: Quickstart, full guide, agent setup docs + wizard-style setup skills
- Benchmarks: honest custom harness (real recall@k) + LOCOMO adapter v2; committed results are mock-backend / mock-judge until #39

~56,400 LOC Rust across 15 crates. memory-installer with 6 runtime converters. 46 E2E tests + 144 bats tests. Cross-CLI matrix report.
~64,626 LOC Rust across 20 crates. First full-platform GitHub Release: v3.1.0.

## What This Is

**Agent Memory is a cognitive architecture for agents** — not just a memory system.

A local, append-only conversational memory system for AI agents (Claude Code, OpenCode, Gemini CLI, GitHub Copilot CLI) that supports agentic search via a permanent hierarchical Table of Contents (TOC), grounded in time-based navigation. The TOC acts as a Progressive Disclosure Architecture: the agent always starts with summaries and navigates downward only when needed. Indexes (vector/BM25) are accelerators, not dependencies.
A local, append-only conversational memory system for AI agents (Claude Code, Gemini CLI, GitHub Copilot CLI, Codex CLI) that supports agentic search via a permanent hierarchical Table of Contents (TOC), grounded in time-based navigation. The TOC acts as a Progressive Disclosure Architecture: the agent always starts with summaries and navigates downward only when needed. Indexes (vector/BM25) are accelerators, not dependencies.

**See:** [Cognitive Architecture Manifesto](../docs/COGNITIVE_ARCHITECTURE.md) for the complete philosophy.

Expand Down Expand Up @@ -270,11 +274,17 @@ Agent Memory implements a layered cognitive architecture:

### Deferred / Future

- Cross-project unified memory
- Per-agent dedup scoping
- Consolidation hook (extract durable knowledge from events, needs NLP/LLM)
- True daemonization (double-fork on Unix)
- API-based summarizer wiring (OpenAI/Anthropic)
- True daemonization (double-fork on Unix) — v3.2 ships launchd/systemd unit files instead (#42); double-fork stays deferred because it does not survive reboot
- Cross-encoder rerank — extension point returns `NotImplemented`; build only if #39 shows retrieval is the bottleneck (#44)
- REST/HTTP endpoint, Python SDK, memory views UI — v3.3+ (new capabilities; v3.2's job is proof and operability)

### Shipped after this list was first written

- API-based summarizer wiring (OpenAI/Anthropic) — Phase 51.5, PR #27, 2026-04-28
- Cross-project federated query — Phase 53.5, PR #25; status remains Experimental
- Retrieval orchestrator reachable from shipped binaries — v3.1 Phase 54, PR #32

### Out of Scope

Expand All @@ -289,7 +299,7 @@ Agent Memory implements a layered cognitive architecture:

**Ingestion via Hooks (Passive Capture)**

Conversations are captured via agent hooks (Claude Code, OpenCode, Gemini CLI, GitHub Copilot CLI). Hook handlers send events to the daemon via gRPC. This is zero-token-overhead passive listening.
Conversations are captured via agent hooks (Claude Code, Gemini CLI, GitHub Copilot CLI, Codex CLI). Hook handlers send events to the daemon via gRPC. This is zero-token-overhead passive listening.

Event types (1:1 from hooks):
| Hook Event | Memory Event |
Expand Down Expand Up @@ -379,8 +389,8 @@ CLI client and agent skill query the daemon. Agent receives TOC navigation tools
| Match expressions for tool maps | Compile-time exhaustive, zero overhead vs HashMap | ✓ Validated v2.7 |
| Write-interceptor for dry-run | Single write_files() handles dry-run; converters produce data only | ✓ Validated v2.7 |
| Hooks generated per-converter | Each runtime's hook mechanism too different for canonical YAML format | ✓ Validated v2.7 |
| OpenCode converter as stub | Full impl deferred; OpenCode runtime format still evolving | — Deferred v2.7 |
| OpenCode converter as stub | Full impl deferred; OpenCode runtime format still evolving | Resolved-by-removal v3.1 Phase 57 (#36) |
| Archive adapters (not delete) | One release cycle before removal; README stubs redirect to installer | ✓ Validated v2.7 |

---
*Last updated: 2026-03-22 after v3.0 milestone start*
*Last updated: 2026-09-01 after v3.1.0 shipped and v3.2 Prove It adopted*
Loading
Loading