Skip to content

fix: activate lifecycle bridges during installer onboarding - #62

Merged
TerminallyLazy merged 1 commit into
mainfrom
codex/installer-activation-bootstrap
Sep 8, 2026
Merged

TerminallyLazy merged 1 commit into
mainfrom
codex/installer-activation-bootstrap

Conversation

@TerminallyLazy

@TerminallyLazy TerminallyLazy commented Sep 8, 2026

Copy link
Copy Markdown
Owner

A fresh install.sh --project --init invoked tree-ring welcome --init, which created the database and guidance but skipped activation.json and native hooks. Onboarding printed “ready,” yet lifecycle activation failed with “activation manifest is unavailable.”

Make welcome --init and init share the same create-only project initializer. Installer onboarding now creates the activation manifest and safe detected harness bridges, reports each harness's actual readiness, and preserves existing files and memory. Plain welcome stays read-only and JSON onboarding still emits exactly one document.

Release CLI 0.15.7 and pair the upcoming Agent Zero 3.4.1 bundle with that minimum. The existing 0.15.6 release remains immutable.

Validation: the full Rust workspace passes; onboarding tests cover activation creation and read-only welcome. The generated-hook acceptance test now starts through welcome --init, then exercises capture and recall across sessions from nested directories with only a project-local CLI.

High-level PR Summary

This PR fixes a bug where installer onboarding (install.sh --project --init via tree-ring welcome --init) created the database and guidance files but skipped the activation manifest and native hooks, causing lifecycle activation to fail. The fix refactors welcome --init to share the same project initialization logic as the init command, ensuring both create the activation manifest and safe harness bridges while preserving existing files. The CLI version is bumped from 0.15.6 to 0.15.7, with Agent Zero 3.4.1 paired to require this minimum version. Read-only welcome behavior and JSON onboarding output format remain unchanged.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 README.md
2 Cargo.toml
3 Cargo.lock
4 crates/tree-ring-memory-cli/Cargo.toml
5 crates/tree-ring-memory-cli/src/main.rs
6 crates/tree-ring-memory-cli/src/welcome.rs
7 crates/tree-ring-memory-cli/tests/harness_activation_acceptance.rs
8 crates/tree-ring-memory-cli/src/activation/adapters.rs

Need help? Join our Discord

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 38 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: e1005015-2f68-44ca-9e87-f60f7c7c45d1

📥 Commits

Reviewing files that changed from the base of the PR and between 889b7c6 and d6826b0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • Cargo.toml
  • README.md
  • crates/tree-ring-memory-cli/Cargo.toml
  • crates/tree-ring-memory-cli/src/activation/adapters.rs
  • crates/tree-ring-memory-cli/src/main.rs
  • crates/tree-ring-memory-cli/src/welcome.rs
  • crates/tree-ring-memory-cli/tests/harness_activation_acceptance.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Initialize lifecycle bridges during installer onboarding

🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Share create-only project initialization between init and installer-driven welcome --init.
• Create activation manifests and detected harness bridges while preserving existing project state.
• Report harness readiness, extend onboarding coverage, and release CLI 0.15.7.
Diagram

graph TD
  W["welcome --init"] --> I["Shared initializer"] --> S["Harness scan"] --> B["Create-only bridges"] --> R["Readiness report"]
  C["init command"] --> I --> D[("Memory store")]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Run init before welcome in the installer
  • ➕ Keeps the two CLI command implementations separate.
  • ➕ Requires little internal CLI refactoring.
  • ➖ Adds another installer subprocess and failure boundary.
  • ➖ Complicates single-document JSON onboarding output.
  • ➖ Allows initialization behavior to drift between entry points.
2. Delegate welcome directly to run_init
  • ➕ Reuses all existing initialization behavior.
  • ➕ Avoids extracting another internal function.
  • ➖ Couples initialization to init-specific text and JSON rendering.
  • ➖ Makes welcome's single response document harder to preserve.
  • ➖ Provides less control over onboarding-specific readiness presentation.

Recommendation: The shared initialize_project function is the best approach because it centralizes state mutation while leaving each command responsible for its own output contract. It also preserves dry-run planning in init and keeps plain welcome read-only.

Files changed (8) +125 / -59

Bug fix (3) +105 / -52
adapters.rsRequire CLI 0.15.7 for Agent Zero 3.4.1 +2/-2

Require CLI 0.15.7 for Agent Zero 3.4.1

• Pairs Agent Zero plugin 3.4.1 with minimum Tree Ring CLI 0.15.7 and updates its capability-contract test fixture.

crates/tree-ring-memory-cli/src/activation/adapters.rs

main.rsExtract shared create-only project initialization +71/-43

Extract shared create-only project initialization

• Separates integration planning from stateful initialization and exposes a shared initializer for both CLI entry points. The initializer creates awareness files and storage, applies safe bridge plans, and returns filtered readiness status while preserving 'init --dry-run'.

crates/tree-ring-memory-cli/src/main.rs

welcome.rsInitialize and report activation during welcome onboarding +32/-7

Initialize and report activation during welcome onboarding

• Routes 'welcome --init' through the shared project initializer and includes activation readiness in text and JSON responses. Tests verify plain welcome remains read-only and initialized onboarding creates activation artifacts.

crates/tree-ring-memory-cli/src/welcome.rs

Tests (1) +9 / -1
harness_activation_acceptance.rsExercise generated hooks through welcome onboarding +9/-1

Exercise generated hooks through welcome onboarding

• Bootstraps the acceptance fixture with JSON 'welcome --init', validates its single onboarding document and activation status, then continues testing cross-session capture and recall through generated project-local hooks.

crates/tree-ring-memory-cli/tests/harness_activation_acceptance.rs

Documentation (1) +5 / -0
README.mdDocument installer onboarding activation behavior +5/-0

Document installer onboarding activation behavior

• Explains that 'welcome --init' creates the same manifest and create-only bridges as 'init', preserves existing state, and reports harness readiness.

README.md

Other (3) +6 / -6
Cargo.lockLock workspace crates at version 0.15.7 +3/-3

Lock workspace crates at version 0.15.7

• Updates the locked versions of the CLI, core, and SQLite workspace packages for the patch release.

Cargo.lock

Cargo.tomlBump the workspace release to 0.15.7 +1/-1

Bump the workspace release to 0.15.7

• Advances the shared workspace package version from 0.15.6 to 0.15.7.

Cargo.toml

Cargo.tomlAlign CLI internal dependencies with 0.15.7 +2/-2

Align CLI internal dependencies with 0.15.7

• Updates the CLI's core and SQLite package constraints to the new workspace patch release.

crates/tree-ring-memory-cli/Cargo.toml

@TerminallyLazy
TerminallyLazy merged commit 8319b40 into main Sep 8, 2026
2 of 3 checks passed
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Custom-root users get partial setup 🐞 Bug ≡ Correctness
Description
welcome::run now sends every requested root into initialize_project, whose activation layer
requires the final directory to be exactly .tree-ring even though the CLI and installer accept any
memory-store root. With --root cache or any other basename, awareness files and memory.sqlite
are created first and manifest loading then errors, so installer onboarding exits unsuccessfully
after leaving a partially initialized store.
Code

crates/tree-ring-memory-cli/src/welcome.rs[33]

+        let (awareness, status) = crate::initialize_project(root)?;
Evidence
The new welcome call enters initialization for every root, while initialization creates awareness
and SQLite state before opening the activation manifest. Activation then requires `memory_root ==
project_root/.tree-ring, conflicting with both the CLI's general --root` option and the
installer's documented --root DIR.

crates/tree-ring-memory-cli/src/welcome.rs[30-36]
crates/tree-ring-memory-cli/src/main.rs[1400-1416]
crates/tree-ring-memory-cli/src/activation/bridge.rs[2193-2199]
crates/tree-ring-memory-cli/src/main.rs[61-67]
install.sh[60-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`welcome --init` now partially initializes custom memory roots before activation rejects them for not being named `.tree-ring`.

## Issue Context
The CLI and installer expose `--root` as a general memory-store directory, but activation enforces a stricter project-local `.tree-ring` shape. Make that contract consistent: either safely support configured roots throughout activation, or reject unsupported roots before creating awareness files or the SQLite database and update the exposed contract accordingly. Add coverage for installer onboarding with a non-default root.

## Fix Focus Areas
- crates/tree-ring-memory-cli/src/welcome.rs[30-36]
- crates/tree-ring-memory-cli/src/main.rs[1391-1416]
- crates/tree-ring-memory-cli/src/activation/bridge.rs[2193-2199]
- install.sh[60-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Nested projects call the wrong store 🐞 Bug ≡ Correctness
Description
initialize_project emits bridge commands that derive project_root from git rev-parse and
hard-code $project_root/.tree-ring, rather than using the memory root whose parent was
initialized. When --root nested/.tree-ring identifies a nested project inside a larger Git
checkout and a native harness is detected there, its new hooks target the outer checkout's store
instead of the initialized nested store.
Code

crates/tree-ring-memory-cli/src/welcome.rs[33]

+        let (awareness, status) = crate::initialize_project(root)?;
Evidence
The newly shared initializer writes bridge definitions for welcome onboarding. ActivationProject
treats the memory root's parent as the project root, but every generated native hook calls
lifecycle_command, which replaces that identity with the enclosing Git top level and always
selects its .tree-ring.

crates/tree-ring-memory-cli/src/welcome.rs[32-34]
crates/tree-ring-memory-cli/src/activation/adapters.rs[35-64]
crates/tree-ring-memory-cli/src/activation/bridge.rs[66-102]
crates/tree-ring-memory-cli/src/activation/lifecycle.rs[14-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Lifecycle hooks created by onboarding can address the outer Git checkout's `.tree-ring` instead of the configured nested project's store.

## Issue Context
Activation derives the project from the configured memory root, but generated hook commands independently redefine the project as the Git top level. Generate commands that resolve the same project and memory root initialized by onboarding, while retaining safe behavior from nested working directories. Add a test for a nested project within a larger Git checkout.

## Fix Focus Areas
- crates/tree-ring-memory-cli/src/welcome.rs[30-34]
- crates/tree-ring-memory-cli/src/main.rs[1407-1416]
- crates/tree-ring-memory-cli/src/activation/lifecycle.rs[14-20]
- crates/tree-ring-memory-cli/src/activation/bridge.rs[66-102]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 19/18, lines 184/200; both must reach the floor). Router rationale: This changes installer onboarding and lifecycle activation across multiple CLI paths, manifest/hook creation, readiness reporting, JSON output, compatibility contracts, and acceptance behavior, creating several independent, easy-to-miss regressions.

Grey Divider

Tip of the day
💡 Did you know, you can tweak Display preferences with a live preview to see your comment before it ships

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

SQLiteMemoryStore::open(&db_path).map_err(|err| err.to_string())?;
(true, Some(awareness))
let (initialized, awareness, status) = if init {
let (awareness, status) = crate::initialize_project(root)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Custom-root users get partial setup 🐞 Bug ≡ Correctness

welcome::run now sends every requested root into initialize_project, whose activation layer
requires the final directory to be exactly .tree-ring even though the CLI and installer accept any
memory-store root. With --root cache or any other basename, awareness files and memory.sqlite
are created first and manifest loading then errors, so installer onboarding exits unsuccessfully
after leaving a partially initialized store.
Agent Prompt
## Issue description
`welcome --init` now partially initializes custom memory roots before activation rejects them for not being named `.tree-ring`.

## Issue Context
The CLI and installer expose `--root` as a general memory-store directory, but activation enforces a stricter project-local `.tree-ring` shape. Make that contract consistent: either safely support configured roots throughout activation, or reject unsupported roots before creating awareness files or the SQLite database and update the exposed contract accordingly. Add coverage for installer onboarding with a non-default root.

## Fix Focus Areas
- crates/tree-ring-memory-cli/src/welcome.rs[30-36]
- crates/tree-ring-memory-cli/src/main.rs[1391-1416]
- crates/tree-ring-memory-cli/src/activation/bridge.rs[2193-2199]
- install.sh[60-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

SQLiteMemoryStore::open(&db_path).map_err(|err| err.to_string())?;
(true, Some(awareness))
let (initialized, awareness, status) = if init {
let (awareness, status) = crate::initialize_project(root)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Nested projects call the wrong store 🐞 Bug ≡ Correctness

initialize_project emits bridge commands that derive project_root from git rev-parse and
hard-code $project_root/.tree-ring, rather than using the memory root whose parent was
initialized. When --root nested/.tree-ring identifies a nested project inside a larger Git
checkout and a native harness is detected there, its new hooks target the outer checkout's store
instead of the initialized nested store.
Agent Prompt
## Issue description
Lifecycle hooks created by onboarding can address the outer Git checkout's `.tree-ring` instead of the configured nested project's store.

## Issue Context
Activation derives the project from the configured memory root, but generated hook commands independently redefine the project as the Git top level. Generate commands that resolve the same project and memory root initialized by onboarding, while retaining safe behavior from nested working directories. Add a test for a nested project within a larger Git checkout.

## Fix Focus Areas
- crates/tree-ring-memory-cli/src/welcome.rs[30-34]
- crates/tree-ring-memory-cli/src/main.rs[1407-1416]
- crates/tree-ring-memory-cli/src/activation/lifecycle.rs[14-20]
- crates/tree-ring-memory-cli/src/activation/bridge.rs[66-102]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant