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
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.15.2"
version = "0.15.3"
edition = "2021"
license = "MIT"
authors = ["TerminallyLazy"]
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ framework-agnostic and does not replace either protocol.
Tree Ring Memory is in protocol-preview status. Current launch links:

- Launch page: <https://terminallylazy.github.io/Tree-Ring-Memory/>
- Launch release: <https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.2>
- Launch release: <https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.3>
- Launch discussion: <https://github.com/TerminallyLazy/Tree-Ring-Memory/discussions/27>
- Rust-native CLI article: <https://terminallylazy.github.io/Tree-Ring-Memory/launch/rust-native-agent-memory-cli.md>
- Feedback issue: <https://github.com/TerminallyLazy/Tree-Ring-Memory/issues/26>
Expand Down Expand Up @@ -259,8 +259,8 @@ sh install.sh --project --init --release latest
sh install.sh --global --install-dir "$HOME/.local"
sh install.sh --no-animation # stable output; kept for explicit script usage
sh install.sh --no-path-update
sh install.sh --release 0.15.2
sh install.sh --archive-url https://example/tree-ring-memory-0.15.2-darwin-arm64.tar.gz --archive-sha256 <sha256>
sh install.sh --release 0.15.3
sh install.sh --archive-url https://example/tree-ring-memory-0.15.3-darwin-arm64.tar.gz --archive-sha256 <sha256>
```

After install, rerun onboarding anytime:
Expand Down
4 changes: 2 additions & 2 deletions crates/tree-ring-memory-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ semver.workspace = true
sha2.workspace = true
tempfile.workspace = true
uuid.workspace = true
tree-ring-memory-core = { path = "../tree-ring-memory-core", version = "0.15.2" }
tree-ring-memory-sqlite = { path = "../tree-ring-memory-sqlite", version = "0.15.2" }
tree-ring-memory-core = { path = "../tree-ring-memory-core", version = "0.15.3" }
tree-ring-memory-sqlite = { path = "../tree-ring-memory-sqlite", version = "0.15.3" }

[dev-dependencies]
rusqlite.workspace = true
66 changes: 52 additions & 14 deletions crates/tree-ring-memory-cli/src/activation/adapters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ pub const AGENT_ZERO_PLUGIN_MANIFEST_ENV: &str = "TREE_RING_AGENT_ZERO_PLUGIN_MA

const AGENT_ZERO_CAPABILITY_FILE: &str = "activation-capability.json";
const AGENT_ZERO_CAPABILITY_KIND: &str = "tree-ring-agent-zero-plugin-capability";
const AGENT_ZERO_PLUGIN_VERSION: &str = "3.1.0";
const AGENT_ZERO_TREE_RING_MIN_VERSION: &str = "0.14.0";
const AGENT_ZERO_TREE_RING_MINOR_VERSION: &str = "0.14";
const AGENT_ZERO_CAPABILITY_CONTRACTS: &[(&str, &str, &str)] =
&[("3.1.0", "0.14.0", "0.14"), ("3.2.0", "0.15.3", "0.15")];
const MAX_AGENT_ZERO_CAPABILITY_BYTES: u64 = 16 * 1024;

/// Project paths used by activation. Adapter plans always target this root.
Expand Down Expand Up @@ -163,22 +162,30 @@ fn read_agent_zero_plugin_manifest(
&read_regular_file_no_follow(&descriptor)?,
)
.ok()?;
let trusted_contract = AGENT_ZERO_CAPABILITY_CONTRACTS.iter().any(
|(plugin_version, minimum_version, minor_version)| {
capability.plugin_version == *plugin_version
&& capability.tree_ring_version.min == *minimum_version
&& capability.tree_ring_version.minor == *minor_version
},
);
if capability.schema_version != 1
|| capability.kind != AGENT_ZERO_CAPABILITY_KIND
|| capability.plugin_id != AGENT_ZERO_PLUGIN_ID
|| capability.plugin_version != AGENT_ZERO_PLUGIN_VERSION
|| capability.activation_protocol_version != ACTIVATION_PROTOCOL_VERSION
|| capability.tree_ring_version.min != AGENT_ZERO_TREE_RING_MIN_VERSION
|| capability.tree_ring_version.minor != AGENT_ZERO_TREE_RING_MINOR_VERSION
|| !trusted_contract
|| !capability.enabled
{
return None;
}

let plugin_yaml = descriptor.parent()?.join("plugin.yaml");
let plugin_yaml = read_regular_file_no_follow(&plugin_yaml)?;
plugin_yaml_matches_capability(std::str::from_utf8(&plugin_yaml).ok()?)
.then_some(AgentZeroPluginManifest::compatible())
plugin_yaml_matches_capability(
std::str::from_utf8(&plugin_yaml).ok()?,
&capability.plugin_version,
)
.then_some(AgentZeroPluginManifest::compatible())
}

/// Opens one regular capability file without following its final path entry.
Expand Down Expand Up @@ -215,7 +222,7 @@ fn read_regular_file_no_follow(_path: &Path) -> Option<Vec<u8>> {
None
}

fn plugin_yaml_matches_capability(plugin_yaml: &str) -> bool {
fn plugin_yaml_matches_capability(plugin_yaml: &str, expected_version: &str) -> bool {
let mut name = None;
let mut version = None;
for line in plugin_yaml.lines() {
Expand All @@ -237,7 +244,7 @@ fn plugin_yaml_matches_capability(plugin_yaml: &str) -> bool {
_ => {}
}
}
name == Some(AGENT_ZERO_PLUGIN_ID) && version == Some(AGENT_ZERO_PLUGIN_VERSION)
name == Some(AGENT_ZERO_PLUGIN_ID) && version == Some(expected_version)
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
Expand Down Expand Up @@ -1106,6 +1113,37 @@ mod tests {
Some(AgentZeroPluginManifest::compatible())
);

fs::write(
plugin.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.1.0\n",
)
.unwrap();
fs::write(
&descriptor,
r#"{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.1.0","activation_protocol_version":1,"tree_ring_version":{"min":"0.14.0","minor":"0.14"},"enabled":true}"#,
)
.unwrap();
assert_eq!(
read_agent_zero_plugin_manifest(&project, &descriptor),
Some(AgentZeroPluginManifest::compatible())
);

fs::write(&descriptor, capability_document(true)).unwrap();
fs::write(
plugin.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.2.0\n",
)
.unwrap();
fs::write(
&descriptor,
capability_document(true).replace(
"\"min\":\"0.15.3\",\"minor\":\"0.15\"",
"\"min\":\"0.14.0\",\"minor\":\"0.14\"",
),
)
.unwrap();
assert!(read_agent_zero_plugin_manifest(&project, &descriptor).is_none());

fs::write(&descriptor, capability_document(false)).unwrap();
assert!(read_agent_zero_plugin_manifest(&project, &descriptor).is_none());

Expand All @@ -1125,7 +1163,7 @@ mod tests {
assert!(read_agent_zero_plugin_manifest(&project, &descriptor).is_none());
fs::write(
plugin.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.1.0\n",
"name: tree_ring_memory\nversion: 3.2.0\n",
)
.unwrap();
assert!(
Expand All @@ -1145,7 +1183,7 @@ mod tests {
fs::create_dir_all(&symlink_parent).unwrap();
fs::write(
symlink_parent.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.1.0\n",
"name: tree_ring_memory\nversion: 3.2.0\n",
)
.unwrap();
let symlink_descriptor = symlink_parent.join(AGENT_ZERO_CAPABILITY_FILE);
Expand All @@ -1157,7 +1195,7 @@ mod tests {
fn write_capability_descriptor(plugin: &Path, enabled: bool) -> PathBuf {
fs::write(
plugin.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.1.0\n",
"name: tree_ring_memory\nversion: 3.2.0\n",
)
.unwrap();
let descriptor = plugin.join(AGENT_ZERO_CAPABILITY_FILE);
Expand All @@ -1167,7 +1205,7 @@ mod tests {

fn capability_document(enabled: bool) -> String {
format!(
r#"{{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.1.0","activation_protocol_version":1,"tree_ring_version":{{"min":"0.14.0","minor":"0.14"}},"enabled":{enabled}}}"#
r#"{{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.2.0","activation_protocol_version":1,"tree_ring_version":{{"min":"0.15.3","minor":"0.15"}},"enabled":{enabled}}}"#
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ fn agent_zero_plugin_descriptor_bootstraps_passive_binding_then_receipt_backed_a
// state until a live compatible descriptor is available again.
fs::write(
&descriptor,
r#"{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.1.0","activation_protocol_version":1,"tree_ring_version":{"min":"0.14.0","minor":"0.14"},"enabled":false}"#,
r#"{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.2.0","activation_protocol_version":1,"tree_ring_version":{"min":"0.15.3","minor":"0.15"},"enabled":false}"#,
)
.unwrap();
let disabled =
Expand Down Expand Up @@ -918,13 +918,13 @@ fn install_agent_zero_plugin(base: &Path) -> PathBuf {
fs::create_dir_all(&plugin).unwrap();
fs::write(
plugin.join("plugin.yaml"),
"name: tree_ring_memory\nversion: 3.1.0\n",
"name: tree_ring_memory\nversion: 3.2.0\n",
)
.unwrap();
let descriptor = plugin.join("activation-capability.json");
fs::write(
&descriptor,
r#"{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.1.0","activation_protocol_version":1,"tree_ring_version":{"min":"0.14.0","minor":"0.14"},"enabled":true}"#,
r#"{"schema_version":1,"kind":"tree-ring-agent-zero-plugin-capability","plugin_id":"tree_ring_memory","plugin_version":"3.2.0","activation_protocol_version":1,"tree_ring_version":{"min":"0.15.3","minor":"0.15"},"enabled":true}"#,
)
.unwrap();
descriptor
Expand Down
2 changes: 1 addition & 1 deletion crates/tree-ring-memory-sqlite/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ rusqlite.workspace = true
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
tree-ring-memory-core = { path = "../tree-ring-memory-core", version = "0.15.2" }
tree-ring-memory-core = { path = "../tree-ring-memory-core", version = "0.15.3" }
uuid.workspace = true

[dev-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions docs/press-kit.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ DOX/Revolve adapters, framework discovery, and a terminal TUI.
- Category: AI agents, developer tools, local-first software, Rust CLI
- License: MIT
- Status: protocol-preview
- Current version: 0.15.2
- Current version: 0.15.3
- Website: <https://terminallylazy.github.io/Tree-Ring-Memory/>
- Repository: <https://github.com/TerminallyLazy/Tree-Ring-Memory>
- Launch release: <https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.2>
- Launch release: <https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.3>
- Launch discussion: <https://github.com/TerminallyLazy/Tree-Ring-Memory/discussions/27>
- Homebrew tap: <https://github.com/TerminallyLazy/homebrew-tree-ring>
- Feedback: <https://github.com/TerminallyLazy/Tree-Ring-Memory/issues/26>
Expand Down
2 changes: 1 addition & 1 deletion marketing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ python3 marketing/scripts/build-campaign-cards.py

- Repository: `https://github.com/TerminallyLazy/Tree-Ring-Memory`
- Launch page: `https://terminallylazy.github.io/Tree-Ring-Memory/`
- Launch release: `https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.2`
- Launch release: `https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.15.3`
- Launch discussion: `https://github.com/TerminallyLazy/Tree-Ring-Memory/discussions/27`
- Homebrew tap: `https://github.com/TerminallyLazy/homebrew-tree-ring`
- Agent-Skills.md main repo listing:
Expand Down