Skip to content
Open
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
14 changes: 14 additions & 0 deletions integrations/shared/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Shared agent memory schemas

`schemas/` is the canonical source for Coding Session, Session, Task, and Decision
seed notes. Host packages carry copies so installation does not depend on a live
repository or another host package. Existing user schemas are never overwritten
by package generation; setup offers missing schemas with approval.

Run `uv run python scripts/sync_memory_schemas.py` after editing these sources.
Use `--check` for a read-only drift check. The Tau package test suite checks every
copy, so `just package-check` enforces consistency across the three hosts.

Claude Code and Tau bundle all four schemas. Codex bundles Coding Session, Task,
and Decision and retains its host-specific general `codex-session.md` schema.
Lifecycle envelopes and optional transcripts are not knowledge schemas.
61 changes: 61 additions & 0 deletions integrations/shared/schemas/coding-session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Coding Session
type: schema
entity: CodingSession
version: 1
schema:
summary?: string, one-paragraph what happened in this coding session
changed_file?(array): string, files created, edited, deleted, or inspected
verification?(array): string, checks run and their result
decision?(array): string, decisions surfaced or created during the session
blocker?(array): string, unresolved blockers or failed approaches
next_step?(array): string, explicit cursor for the next coding session
produced?(array): Entity, notes or artifacts created or updated
settings:
validation: warn
frontmatter:
project: string, the Basic Memory project this session belongs to
started: string, when the session began or checkpoint was created
repository: string, stable repository identifier such as owner/name
repo_root: string, Git repository root for this checkout
cwd: string, working directory for the session
branch: string, checked-out Git branch or HEAD when detached
git_sha: string, exact Git commit at checkpoint time
ended?: string, when the session was checkpointed
status?(enum, lifecycle of the checkpoint): [open, resumed, closed]
pull_request_number?: string, current pull request number as a queryable identifier
pull_request_title?: string, current pull request title
pull_request_url?: string, canonical pull request URL
pull_request_state?(enum, pull request state at checkpoint time): [open, closed, merged]
pull_request_base?: string, pull request base branch
pull_request_head?: string, pull request head branch
username?: string, operating-system user that created the checkpoint
hostname?: string, host that created the checkpoint
tau_session_id?: string, Tau session identifier
claude_session_id?: string, Claude Code session identifier
codex_session_id?: string, Codex session identifier
codex_turn_id?: string, Codex turn identifier
trigger?: string, compaction trigger or deliberate checkpoint source
model?: string, active model slug when known
capture?(enum, how this checkpoint was produced): [extractive, deliberate, summarized]
---

# Coding Session

A **CodingSession** is a resumable engineering checkpoint whose repository
identity is structured and queryable. Required Git fields make it possible to
find the exact work cursor without parsing prose.

Examples:

`search_notes(note_types=["coding_session"], metadata_filters={"repository": "owner/repo"})`

`search_notes(note_types=["coding_session"], metadata_filters={"pull_request_number": "123"})`

`search_notes(note_types=["coding_session"], metadata_filters={"codex_session_id": "<id>"})`

Pull-request fields are optional because valid coding work can precede a pull
request. When a pull request exists, checkpoint writers populate the complete
pull-request field set. Multiple checkpoints from one agent chat share the
relevant `claude_session_id`, `codex_session_id`, or `tau_session_id`; each new checkpoint can link
to its verified predecessor with `continues [[Previous checkpoint title]]`.
43 changes: 43 additions & 0 deletions integrations/shared/schemas/decision.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Decision
type: schema
entity: Decision
version: 1
schema:
decision: string, the choice that was made
rationale?: string, why this choice over the alternatives
alternative?(array): string, options that were considered and not taken
consequence?(array): string, what this decision commits us to
context?: string, the situation that prompted the decision
affects?(array): Entity, work or notes this decision bears on
supersedes?: Entity, a prior decision this one replaces
settings:
validation: warn
frontmatter:
status?(enum, lifecycle of the decision): [open, accepted, superseded, rejected]
decided?: string, when the decision was made (ISO timestamp)
project?: string, the Basic Memory project this decision belongs to
---

# Decision

A **DecisionNote** is a durable record of a real choice — one with alternatives
and a rationale, not a passing preference. Basic Memory host integrations
encourage agents to capture these as decisions are made or explicitly requested.

Decisions are found by structured recall:
`search_notes(metadata_filters={"type": "decision", "status": "open"})`.

## What makes a good DecisionNote

- **decision** — state the choice plainly.
- **rationale** + **alternative** — why this, and what was rejected. This is the
part that saves a future session from relitigating the same ground.
- **consequence** — what the choice commits the work to.
- **affects** / **supersedes** — relations that wire the decision into the graph.

## Frontmatter

`type: decision` plus `status` make decisions queryable. Capture decisions
sparingly — one note per genuine decision, not per opinion. Validation is `warn`,
never blocking.
56 changes: 56 additions & 0 deletions integrations/shared/schemas/session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Session
type: schema
entity: Session
version: 1
schema:
summary?: string, one-paragraph what-happened this session
context?(array): string, key context needed to resume after memory loss
next_step?(array): string, explicit cursor for the next session
decision?(array): string, decisions surfaced during the session
problem?(array): string, problems hit — including attempted-and-rejected approaches
produced?(array): Entity, notes created or updated during the session
settings:
validation: warn
frontmatter:
project: string, the Basic Memory project this session belongs to
started: string, when the session began (ISO timestamp)
ended?: string, when the session was checkpointed
status?(enum, lifecycle of the checkpoint): [open, resumed, closed]
cwd?: string, the working directory the session ran in
username?: string, operating-system user that created the checkpoint
hostname?: string, host that created the checkpoint
tau_session_id?: string, Tau session identifier
claude_session_id?: string, Claude Code session identifier
capture?(enum, how this checkpoint was produced): [extractive, deliberate, summarized]
---

# Session

A **SessionNote** is a resume checkpoint. Basic Memory host integrations
write these at their supported lifecycle boundaries or on an explicit checkpoint
request. It records what the
session was doing so the next session can pick up where this one left off.

Sessions are found by the SessionStart hook via structured recall:
`search_notes(metadata_filters={"type": "session"}, after_date="3d")`.

In a **coding setup** (`sessionProfile: "coding"`), checkpoints use the Coding
Session schema instead — it adds required, queryable Git identity
(`repository`, `branch`, `git_sha`, pull-request fields). This schema stays the
general-purpose checkpoint.

## What goes in a SessionNote

- **summary** — a short paragraph of what happened (richer once summarized
checkpoints replace the extractive first cut).
- **context** / **next_step** — the cursor: what's in flight and what to do next.
- **decision** / **problem** — choices made and dead-ends hit, so the next
session doesn't repeat them.
- **produced** — relations to the notes this session created or changed.

## Frontmatter

`type: session` and `status` are the queryable fields that power recall. `warn`
validation means a missing field is surfaced, never blocking — the user's flow
is never gated on schema conformance.
39 changes: 39 additions & 0 deletions integrations/shared/schemas/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: Task
type: schema
entity: Task
version: 1
schema:
description: string, what needs to be done
status?(enum, current state): [active, blocked, done, abandoned]
assigned_to?: string, who is working on this
steps?(array): string, ordered steps to complete
current_step?: integer, which step number we're on (1-indexed)
context?: string, key context needed to resume after memory loss
started?: string, when work began
completed?: string, when work finished
blockers?(array): string, what's preventing progress
parent_task?: Task, parent task if this is a subtask
settings:
validation: warn
---

# Task

A **Task** is work-in-progress tracked as a note, so it survives context
compaction and shows up in the next session's brief. This schema is the same one
the framework-agnostic [`memory-tasks`](https://github.com/basicmachines-co/basic-memory/tree/main/skills/memory-tasks)
skill defines — kept identical here so the plugin and the skill agree on the
shape. For the full task workflow (creating, updating, completing), use that
skill.

Tasks are found by the SessionStart hook via structured recall:
`search_notes(metadata_filters={"type": "task", "status": "active"})`.

## Frontmatter vs observations

Put queryable fields (`status`, `priority`, `current_step`) in frontmatter so
`metadata_filters` can find them, and mirror them as `- [status] active`
observations so `schema_validate` sees them. `note_type="Task"` is stored as
lowercase `task` in frontmatter, so search with `note_types=["task"]`.
Validation is `warn` — advisory, never blocking.
52 changes: 46 additions & 6 deletions integrations/tau/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,50 @@

Issue: https://github.com/basicmachines-co/basic-memory/issues/1487
Integration: https://github.com/basicmachines-co/basic-memory/pull/1489
Required host work: https://github.com/huggingface/tau/pull/683
Required host work: https://github.com/huggingface/tau/pull/687

## Product contract

A fresh or compacted session recovers the objective, decisions, unfinished work,
verified findings, and next action through the shared Basic Memory graph. Full
MCP tool access supports that loop; it is not a substitute for it.

## Shared Basic Memory contract

`knowledge.py` models general/coding profiles at the configuration boundary and
collects Git/PR metadata into a small frozen value. The lifecycle selects an
explicit user-approved checkout profile; it does not discover write authority
from repository files. The general profile remains backward compatible with
existing `project` and capture controls. Coding profiles carry their own explicit
write project and read-only sources. Global lifecycle flags still govern both.

General snapshots use `session`; coding snapshots use `coding_session` with
required queryable Git identity. Canonical schemas live in
`integrations/shared/schemas`, with checked copies in each host package. Tau uses
the same schema categories and repository queries as the hook-backed integrations,
without importing the CLI or executing `bm hook`. Setup offers missing schemas
with consent; it does not overwrite user knowledge or customized definitions.

Repository identity, not cwd, scopes coding history across checkouts. Active tasks
and open decisions remain project knowledge; shared-project reads carry explicit
read-only labels. Broad coding-session topic/feed queries are excluded so another
repository's checkpoint cannot bypass the scope. Receipt recovery still uses
immutable source identity, independently of retrieval conventions.

Git metadata is required only for a new coding checkpoint; reconciliation never
needs current Git state. Optional GitHub PR lookup does not make local coding
require authentication. Subprocess cancellation retires the metadata reader before
returning. No detached writer, additional lifecycle telemetry store, or framework
of host adapters is introduced.

## Host dependencies, implemented separately

Stock Tau 0.4.1 only notifies extensions around overflow compaction. Its queued
custom messages run as follow-ups, which can cause an extra model response even
with trigger_turn=False. Its public context cannot read persisted custom receipts
or request a tool-free summary through the active provider.

Tau #683 supplies:
Tau #687 supplies:

1. Awaited extension start/end notifications around manual, detailed manual,
threshold and overflow compaction. No-op checks emit nothing. Failure and
Expand All @@ -31,7 +59,9 @@ Tau #683 supplies:
without queuing another turn.
5. Shutdown/start notifications around in-place tree branches on the same runtime.

The package pins the tested fork SHA until these interfaces are released upstream.
The package pins the Basic Machines fork at `d8216af` until these interfaces are
released upstream. That revision deep-copies branch entries once at the session
boundary; the extension facade returns the isolated snapshot without recopying it.
It does not modify installed Tau or pretend #506 is fully closed: that issue's
threshold/manual frontend-iterator/TUI-status work is separate from extension
callback delivery. Persisted-entry notifications are not required; branch snapshots
Expand Down Expand Up @@ -67,10 +97,13 @@ separate snapshots linked to the prior active-branch checkpoint. Transcript note
are distinct, opt-in, immutable segments; handoffs link their captured sources.

Startup reads confirmed active-branch checkpoints before broader scoped results,
expands the checkpoint's graph neighborhood, and includes shared recent activity.
expands the checkpoint's graph neighborhood, then retrieves active tasks, open
decisions, explicitly approved shared sources, and bounded topic matches. General
profiles also include broader recent activity; coding profiles exclude that
unscoped feed.
Filter-only search supplies an epoch after_date to obtain BM's newest-first order
without excluding long-idle modern sessions. Topic search also retrieves shared
coding_session/task/decision notes. The inserted brief is bounded and labeled as
without excluding long-idle modern sessions. Coding-session retrieval is
repository-scoped; topic queries retrieve tasks and decisions only. The inserted brief is bounded and labeled as
untrusted historical reference, not current repository facts.

## Failure and privacy policy
Expand All @@ -95,3 +128,10 @@ suite proves file writes, reads, searches, transcripts, checkpoints, compaction
reference restoration, reload and resume in temporary local projects. Synthesis
uses deterministic providers, so these tests do not claim live-model quality or
paid/cloud account end-to-end verification.

## Follow-up boundary

A Tau sidebar can expose the active destination, recall sources, confirmed
checkpoint, and unfinished tasks through the supported extension UI. That is a
separate change after this contract is verified; a custom frontend is not required
for correct memory, and this package makes no sidebar/frontend behavior claims.
Loading
Loading