Skip to content

Commit f4255b3

Browse files
authored
Merge pull request #326 from rtk-ai/develop
Next Release
2 parents 65ae008 + c5e43b2 commit f4255b3

16 files changed

Lines changed: 2512 additions & 66 deletions

File tree

.github/workflows/cd.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ jobs:
209209
210210
git push origin "$BRANCH"
211211
212+
# Ensure the 'automated' label exists before referencing it: a missing
213+
# label makes `gh pr create --label` fail and aborts the back-merge PR
214+
# ("could not add label: 'automated' not found"). Idempotent.
215+
gh label create automated \
216+
--color ededed \
217+
--description "Automated PR (back-merge / release tooling)" \
218+
2>/dev/null || true
219+
212220
gh pr create \
213221
--base develop \
214222
--head "$BRANCH" \

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,40 @@ jobs:
5252
- uses: Swatinem/rust-cache@v2
5353
- run: cargo test --workspace
5454

55+
# Validates the fully-static musl binary shipped for old-glibc distros
56+
# (issue #330: the glibc binaries need symbols newer than Debian Bookworm's
57+
# glibc 2.36). Embeddings are dropped because `ort`/onnxruntime ships only
58+
# glibc prebuilt binaries and can't link statically against musl.
59+
musl:
60+
name: musl static build
61+
needs: clippy
62+
runs-on: ubuntu-latest
63+
steps:
64+
- uses: actions/checkout@v4
65+
- uses: dtolnay/rust-toolchain@stable
66+
with:
67+
targets: x86_64-unknown-linux-musl
68+
- uses: Swatinem/rust-cache@v2
69+
- name: Install musl tools
70+
run: sudo apt-get update && sudo apt-get install -y musl-tools
71+
- name: Build static musl binary (no embeddings)
72+
# sqlite-vec.c uses BSD type names (u_int8_t/u_int16_t/u_int64_t) that
73+
# glibc provides but musl does not; map them to the standard names.
74+
env:
75+
CFLAGS_x86_64_unknown_linux_musl: "-Du_int8_t=uint8_t -Du_int16_t=uint16_t -Du_int32_t=uint32_t -Du_int64_t=uint64_t"
76+
run: >-
77+
cargo build --release --target x86_64-unknown-linux-musl -p icm-cli
78+
--no-default-features --features "backend-sqlite,tui,http-api"
79+
- name: Verify the binary is fully static
80+
run: |
81+
bin=target/x86_64-unknown-linux-musl/release/icm
82+
file "$bin"
83+
if ldd "$bin" 2>&1 | grep -Eq "statically linked|not a dynamic executable"; then
84+
echo "OK: statically linked — runs on any Linux regardless of glibc"
85+
else
86+
echo "FAIL: binary is dynamically linked"; ldd "$bin"; exit 1
87+
fi
88+
5589
security:
5690
name: security scan
5791
needs: clippy

.github/workflows/release.yml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,22 @@ jobs:
4545
- target: aarch64-apple-darwin
4646
os: macos-latest
4747
archive: tar.gz
48+
# Build the glibc binaries on an older runner (glibc 2.35) so they
49+
# run on Debian 12 "Bookworm" (glibc 2.36) and other current distros
50+
# — ubuntu-latest's glibc is too new (issue #330).
4851
- target: x86_64-unknown-linux-gnu
49-
os: ubuntu-latest
52+
os: ubuntu-22.04
5053
archive: tar.gz
5154
- target: aarch64-unknown-linux-gnu
55+
os: ubuntu-22.04
56+
archive: tar.gz
57+
# Fully-static musl binary for old-glibc distros (issue #330:
58+
# Debian Bookworm's glibc 2.36 is older than ubuntu-latest's).
59+
# No embeddings: ort/onnxruntime has no static musl build.
60+
- target: x86_64-unknown-linux-musl
5261
os: ubuntu-latest
5362
archive: tar.gz
63+
flags: --no-default-features --features backend-sqlite,tui,http-api
5464
- target: x86_64-pc-windows-msvc
5565
os: windows-latest
5666
archive: zip
@@ -70,6 +80,12 @@ jobs:
7080
sudo apt-get update
7181
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
7282
83+
- name: Install musl tools
84+
if: matrix.target == 'x86_64-unknown-linux-musl'
85+
run: |
86+
sudo apt-get update
87+
sudo apt-get install -y musl-tools
88+
7389
- name: Build (cross aarch64)
7490
if: matrix.target == 'aarch64-unknown-linux-gnu'
7591
run: cargo build --release --target ${{ matrix.target }} -p icm-cli --features vendored-openssl
@@ -78,7 +94,11 @@ jobs:
7894

7995
- name: Build
8096
if: matrix.target != 'aarch64-unknown-linux-gnu'
81-
run: cargo build --release --target ${{ matrix.target }} -p icm-cli
97+
# Target-specific, so a no-op for non-musl targets: sqlite-vec.c uses
98+
# BSD type names (u_int8_t/…) that glibc provides but musl does not.
99+
env:
100+
CFLAGS_x86_64_unknown_linux_musl: "-Du_int8_t=uint8_t -Du_int16_t=uint16_t -Du_int32_t=uint32_t -Du_int64_t=uint64_t"
101+
run: cargo build --release --target ${{ matrix.target }} -p icm-cli ${{ matrix.flags }}
82102

83103
- name: Package (Unix)
84104
if: matrix.archive == 'tar.gz'
@@ -101,7 +121,8 @@ jobs:
101121

102122
build-deb:
103123
name: Build .deb
104-
runs-on: ubuntu-latest
124+
# Older glibc (2.35) so the packaged binary runs on Debian 12 (#330).
125+
runs-on: ubuntu-22.04
105126
steps:
106127
- name: Checkout
107128
uses: actions/checkout@v4

CONTRIBUTING.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Contributing to ICM
2+
3+
**Welcome!** We appreciate your interest in contributing to ICM.
4+
5+
## Quick Links
6+
7+
- [Report an Issue](../../issues/new)
8+
- [Open Pull Requests](../../pulls)
9+
- [Start a Discussion](../../discussions)
10+
11+
---
12+
13+
## What is ICM?
14+
15+
**ICM (Infinite Context Memory)** is a persistent long-term memory for LLM agents, written in Rust. It stores memories with embeddings in SQLite, does hybrid retrieval (BM25/FTS5 + vector similarity), manages temporal decay and consolidation, and exposes an MCP server so tools like Claude Code, Codex, and others can store and recall memories across sessions.
16+
17+
---
18+
19+
## Ways to Contribute
20+
21+
| Type | Examples |
22+
|------|----------|
23+
| **Report** | File a clear issue with steps to reproduce, expected vs actual behavior |
24+
| **Fix** | Bug fixes, correctness issues, durability/robustness improvements |
25+
| **Build** | New features (for core features — storage backends, retrieval, MCP tools — discuss with maintainers first) |
26+
| **Review** | Review open PRs, test changes locally, leave constructive feedback |
27+
| **Document** | Improve docs, clarify behavior |
28+
29+
---
30+
31+
## Design Philosophy
32+
33+
A few principles guide ICM. Understanding them helps your contribution fit naturally.
34+
35+
### Correctness over cleverness
36+
37+
ICM is positioned as a durable, cross-host brain shared by multiple agents writing the same store concurrently. Data loss and silent corruption are the worst failure modes. Prefer the safe, boring path; back up before destructive operations; never claim a fix you can't verify.
38+
39+
### No panics in production code
40+
41+
No `.unwrap()` / `.expect()` / `panic!` in non-test code. Use typed errors (`thiserror`) in libraries and `anyhow` with `.context()` at the CLI boundary, and propagate with `?`. A hook or MCP tool must degrade gracefully, never crash the caller.
42+
43+
### Async-first I/O, cheap hot paths
44+
45+
All I/O is async where it matters. Keep the per-hook and per-prompt paths cheap — they run on every tool call. Don't load heavy models or do network I/O on a path that must return in milliseconds.
46+
47+
### Backends are additive, selected at runtime
48+
49+
SQLite is the default in-process backend; Postgres/OpenSearch are compiled in and chosen at runtime via `ICM_DB_BACKEND`. New storage features should respect this split and not assume SQLite.
50+
51+
### Extensibility
52+
53+
Reuse existing components and traits (`MemoryStore`, `Embedder`, …) instead of duplicating. New core features (backends, retrievers, MCP tools) are worth discussing before you build.
54+
55+
---
56+
57+
## Commit Messages & Changelog
58+
59+
ICM uses [Conventional Commits](https://www.conventionalcommits.org/) and [release-please](https://github.com/googleapis/release-please) to **auto-generate CHANGELOG.md, version bumps, and GitHub releases**. Never edit `CHANGELOG.md` manually — it is fully managed by release-please from your commit messages.
60+
61+
### Commit format
62+
63+
```
64+
<type>(<scope>): <short description>
65+
```
66+
67+
| Type | Semver Impact | When to Use |
68+
|------|---------------|-------------|
69+
| `feat` | Minor | New features, new MCP tools, new backends |
70+
| `fix` | Patch | Bug fixes, corrections |
71+
| `perf` | Patch | Performance improvements |
72+
| `refactor` || Code restructuring (no changelog entry) |
73+
| `docs` || Documentation only |
74+
| `chore` || Maintenance, CI, deps |
75+
| `feat!` / `fix!` | Major | Breaking changes (add `!` after type) |
76+
77+
**Scope** should match the module or area: `store`, `mcp`, `retriever`, `hooks`, `cli`, `cicd`, etc.
78+
79+
### Examples
80+
81+
```
82+
feat(mcp): add icm_memory_health tool
83+
fix(store): open read-only connections WAL-aware instead of immutable
84+
perf(retriever): reuse the FTS statement across recall calls
85+
feat!(store): change the embedding column layout
86+
```
87+
88+
These commit messages become CHANGELOG entries when release-please cuts a release. Write them as if users will read them.
89+
90+
---
91+
92+
## Branch Naming Convention
93+
94+
Git branch names cannot include spaces or colons, so we use slash-prefixed names.
95+
96+
| Prefix | When to Use |
97+
|--------|-------------|
98+
| `fix/` | Bug fixes, corrections, minor adjustments |
99+
| `feat/` | New features |
100+
| `chore/` | CI/CD, deps, maintenance, breaking changes |
101+
102+
Combine the prefix with a scope if it adds clarity and finish with a short, kebab-case slug:
103+
104+
```
105+
fix/store-readonly-live-connection
106+
feat/mcp-http-proxy-mode
107+
chore/release-pipeline-cleanup
108+
```
109+
110+
---
111+
112+
## Pull Request Process
113+
114+
### Scope Rules
115+
116+
**Each PR must focus on a single feature, fix, or change.** The diff must stay in-scope with the PR title and body. Out-of-scope changes (unrelated refactors, drive-by fixes, formatting of untouched files) go in a separate PR. For large features, prefer several logical, independently-reviewable PRs over one enormous one.
117+
118+
### 1. Create your branch
119+
120+
```bash
121+
git checkout develop
122+
git pull origin develop
123+
git checkout -b feat/scope-your-clear-description
124+
```
125+
126+
### 2. Make your changes
127+
128+
Respect the existing workspace layout (`crates/icm-*`). Keep functions short and focused. Comments explain *why*, not *what*.
129+
130+
### 3. Add tests
131+
132+
Every change **must** include tests where it has a runtime surface. See [Testing](#testing).
133+
134+
### 4. Add documentation
135+
136+
Update docs for new features and changes to already-documented behavior.
137+
138+
### 5. Target `develop`
139+
140+
Open your Pull Request against the **`develop`** branch. `main` is reserved for stable releases — only maintainer `develop``main` PRs (cut via release-please) target it.
141+
142+
### 6. Review & CI
143+
144+
1. **Maintainer review** — a maintainer reviews for quality and alignment.
145+
2. **CI/CD checks** — automated tests and lints must pass.
146+
3. **Resolution** — address feedback from review or CI.
147+
148+
### 7. Integration & release
149+
150+
```
151+
your branch --> develop (review + CI + integration) --> main (versioned release via release-please)
152+
```
153+
154+
---
155+
156+
## Testing
157+
158+
### Pre-Commit Gate (mandatory)
159+
160+
All three must pass before any PR:
161+
162+
```bash
163+
cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace
164+
```
165+
166+
### PR Testing Checklist
167+
168+
- [ ] Unit tests added/updated for changed code
169+
- [ ] Integration/e2e coverage where the change has a runtime surface
170+
- [ ] No `.unwrap()` / `.expect()` / `panic!` in non-test code
171+
- [ ] `cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace` passes
172+
- [ ] Manual test: exercise the affected flow (CLI command, MCP tool, hook) and inspect the result
173+
174+
---
175+
176+
## Questions?
177+
178+
- **Bug reports & features**: [Issues](../../issues)
179+
- **Discussions**: [GitHub Discussions](../../discussions)
180+
181+
**For external contributors**: your PR undergoes automated and manual security review (see [SECURITY.md](SECURITY.md)).
182+
183+
---
184+
185+
**Thank you for contributing to ICM!**

DISCLAIMER.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Disclaimer
2+
3+
## No Warranty
4+
5+
This software is provided "AS IS", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. The entire risk as to the quality and performance of the software is with you.
6+
7+
## Limitation of Liability
8+
9+
In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software. This includes, without limitation, any direct, indirect, incidental, special, exemplary, or consequential damages (including but not limited to loss of data, loss of profits, or business interruption).
10+
11+
## Precompiled Binaries
12+
13+
Precompiled binaries are provided solely for convenience and are covered by the same license as the source code (Apache License 2.0). They are provided without warranties or conditions of any kind. You are responsible for verifying the integrity and suitability of any binary before use. Always verify checksums when available (the installer verifies each download against the release's `checksums.txt`).
14+
15+
## Your Data
16+
17+
ICM stores your memories in a local SQLite database on your machine. It does **not** phone home: the "hook telemetry" it records (see `icm hook-log` / `icm hook-stats`) stays in your local database and is never transmitted. Any embedding provider or LLM CLI you explicitly configure is contacted under your own credentials — review those providers' terms. You are responsible for the confidentiality and backups of your store.
18+
19+
## Third-Party Dependencies
20+
21+
This software incorporates third-party open-source components, each governed by their respective licenses. The authors make no representations or warranties regarding these dependencies and accept no liability for any issues arising from their use.
22+
23+
## Use at Your Own Risk
24+
25+
This software interacts with your development environment, file system, and any AI tools you connect it to. It is your responsibility to ensure that its use is appropriate for your environment and complies with any applicable policies, regulations, or agreements. The authors are not responsible for any unintended side effects resulting from its use.
26+
27+
---
28+
29+
See [LICENSE](LICENSE) for the full terms of the Apache License 2.0 under which this software is distributed.

0 commit comments

Comments
 (0)