Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5203150
fix(policy): rewrite read-only classifier to token-parse with default…
blackaxgit Jun 6, 2026
26a7f65
fix(policy): make L1 cache key injective with NUL separator
blackaxgit Jun 6, 2026
d925494
fix(policy): normalize ':' symmetrically in glob_match pattern and text
blackaxgit Jun 6, 2026
c3ddd54
refactor(core): add single-source Codex trust reader in clx-core
blackaxgit Jun 6, 2026
600d655
refactor(core): type the trustlist errors and drop dead Error variants
blackaxgit Jun 6, 2026
3dee726
fix(llm): bound the Azure health probe with a 2s per-request timeout
blackaxgit Jun 6, 2026
661edf2
fix(llm): make fallback cooldown survive across hook processes
blackaxgit Jun 6, 2026
6d97efc
fix(credentials): retry transient zero-byte reads on the credential path
blackaxgit Jun 6, 2026
32edb83
fix(storage): wrap v1 migration in a transaction for atomicity
blackaxgit Jun 6, 2026
29f4729
fix(core): correct percentile doc and remove redaction byte-as-char h…
blackaxgit Jun 6, 2026
c6136ff
fix(recall): distinguish a degraded store from a genuine empty result
blackaxgit Jun 7, 2026
c8773da
fix(mcp): decode JSON-RPC lines once to avoid UTF-8 split corruption
blackaxgit Jun 7, 2026
9f30574
refactor(hook): remove dead host-less aggregator duplicate
blackaxgit Jun 7, 2026
f9fd72a
refactor(hook): drop the half-wired HookDeps seam and test-only parse…
blackaxgit Jun 7, 2026
6393b70
refactor(cli): delete dead duplicate Codex trust reader (moved to clx…
blackaxgit Jun 7, 2026
a6bf3ec
refactor(hook): consolidate trust reader, drop dead block, split god …
blackaxgit Jun 7, 2026
d5a8b5f
chore(security): allowlist the synthetic PEM fixture for gitleaks
blackaxgit Jun 7, 2026
11230a5
docs(core): document why LlmConfigError stays separate from crate::Error
blackaxgit Jun 7, 2026
95dce60
test(llm): unify serial key so fallback/azure tests don't race on the…
blackaxgit Jun 7, 2026
7f3448f
fix(policy): close arbitrary-fd redirection and sed combined-flag byp…
blackaxgit Jun 7, 2026
8377f73
fix(recall): mark degraded when FTS5 errors even if substring fallbac…
blackaxgit Jun 7, 2026
d55de31
fix(llm): honor cross-process cooldown in is_available
blackaxgit Jun 7, 2026
7f08df6
fix(policy): parse sed substitution flags and catch named-fd redirection
blackaxgit Jun 7, 2026
45b855c
chore(fmt): apply rustfmt to fix-campaign edits
blackaxgit Jun 7, 2026
3af0db6
feat(core): add shared learned-pattern detectors (env-strip, secret, …
blackaxgit Jun 7, 2026
775531a
feat(policy): graylist ask-tier, asymmetric compound matching, redire…
blackaxgit Jun 7, 2026
054c64f
feat(storage): v9 migration purges secret/malformed learned rules
blackaxgit Jun 7, 2026
4135c38
feat(embeddings): route-derived embedding dimension; clarify default_…
blackaxgit Jun 7, 2026
609ec51
feat(learning): gate secrets/malformed and stop learning from automat…
blackaxgit Jun 7, 2026
e7529c1
feat(hook): allow agent-memory writes while still guarding settings/h…
blackaxgit Jun 7, 2026
d964e86
feat(host): honor CLAUDECODE so interactive Claude Code is not mistak…
blackaxgit Jun 7, 2026
30676f3
feat(embeddings): use route-derived dimension in status/rebuild/backfill
blackaxgit Jun 7, 2026
773f963
fix(health): warn on unresolved routes instead of failing on hardcode…
blackaxgit Jun 7, 2026
55cc1d3
feat(cli): add clx config get/set with isolated validation and restor…
blackaxgit Jun 7, 2026
ca17d5c
feat(cli): add clx rules export/import with validation and scope-awar…
blackaxgit Jun 7, 2026
d680dae
fix(cli): reject unknown rule_type on import instead of defaulting to…
blackaxgit Jun 7, 2026
f62a1fd
fix(policy): allow agent-memory redirects while denying sensitive-tar…
blackaxgit Jun 7, 2026
eed6006
chore(release): 0.11.0
blackaxgit Jun 7, 2026
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
1 change: 1 addition & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ paths = [
'''crates/clx-mcp/src/tests\.rs''',
'''crates/clx-core/tests/.*_poc\.rs''',
'''crates/clx-core/tests/redaction_scheme_floor_regression\.rs''',
'''crates/clx-core/tests/security_fixed_vectors_regression\.rs''',
]
# Named synthetic tokens, anchored and with a required tail.
regexes = [
Expand Down
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

## [0.11.0] - 2026-06-07

A large hardening + features release: a security fix campaign followed by a
10-issue source-improvement program. Includes a one-time schema migration
(v8 → v9); older binaries will refuse a v9 database.

### Security

- **Read-only command classifier rewritten (token-parse + default-deny).** The
previous allow-by-name + substring heuristic auto-allowed many command-executing
or file-writing commands under `auto_allow_reads`. The classifier now tokenizes
(quote-aware), screens shell metacharacters, segments compound commands, and
fails closed — closing bypasses via env-prefixed execution, `awk` `system()`,
`find`/`fd` exec, interpreter `-e`/verbose flags, `git config`/`branch`/`tag`/
`remote`, `tar`/`zip`, `sed` exec/write flags, arbitrary-fd redirection, and
shell-metacharacter evasion.
- **Learned-rules database no longer ingests secrets or malformed patterns.**
Leading `ENV=VALUE` assignments are stripped before pattern extraction; raw
secret-bearing and compound/substitution commands are rejected before any rule
is stored; a v9 migration purges pre-existing secret/malformed rows (logged
redacted).
- **L0 now denies shell redirection/`tee`/`cp`/`mv`/`dd` writes into protected
config directories** (CLX, Codex, Cursor, and sensitive agent-config targets).
- **Auto-blacklist no longer learns from automated LLM denials** — only genuine
user rejections create deny rules, so an explicit allow can't be overridden by
the validator's own caution.
- **L1 verdict cache key is now injective** (NUL separator), preventing reuse of a
cached decision for a different command/cwd.
- **`clx rules import` strictly validates rule types** (unknown/`graylist` values
are rejected, never coerced to allow).
- Additional hardening: single-source Codex trust reader, bounded credential read
retry, glob-match colon symmetry, and removal of dead security-path code.

### Added

- **Graylist (ask) policy tier** with asymmetric compound-command matching: a
compound is denied if any segment is blacklisted and allowed only if every
non-`cd` segment is whitelisted.
- **`clx config get` / `clx config set`** for dotted-key configuration tuning
(global scope, validate-or-restore on write).
- **`clx rules export` / `clx rules import`** (validated + redacted on import) and
scope-aware **`clx rules reset --learned-only` (default) / `--all`**.
- **CLAUDECODE-based host detection** so interactive Claude Code is not mistaken
for Codex (which would turn an `ask` into a hard block).
- **Route-derived embedding dimension** (`CapabilityRoute.dimension` + model
registry) with stored-vs-route drift detection; the Azure embed request now
sends the configured dimension.
- Expanded read-only allow-set (`cd`, `sort`, `uniq`, `cut`, `column`, guarded).

### Fixed

- **`clx health`** warns on unresolved/legacy routes instead of failing against
hardcoded Ollama models, and uses the configured embedding model.
- Agent memory files are writable again while settings/hooks remain protected.
- MCP JSON-RPC line reads decode UTF-8 once, fixing multibyte corruption at buffer
boundaries.
- Recall reports a degraded signal instead of masking a broken store as "no
results".
- Azure health probe bounded by a 2s timeout; the LLM fallback cooldown now
survives across one-shot hook processes; the v1 storage migration is
transactional.

### Changed

- **Schema version 8 → 9** (one-time purge migration; older binaries refuse a v9
database).
- Documentation: clarified that disabling L1 (`layer1_enabled=false`) forces
`ask`; `default_decision` governs runtime L1 failure/inconclusive outcomes only.

## [0.10.1] - 2026-05-30

### Security
Expand Down
10 changes: 6 additions & 4 deletions Cargo.lock

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

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
]

[workspace.package]
version = "0.10.1"
version = "0.11.0"
edition = "2024"
license = "MPL-2.0"
authors = ["CLX Contributors"]
Expand Down Expand Up @@ -78,6 +78,10 @@ url = "2"
# Regex
regex = "1"

# Shell-aware tokenizer for read-only command classification. We use ONLY
# `shlex::split` (RUSTSEC-2024-0006 affects `quote`/`join`, fixed at 1.3.0).
shlex = "1.3"

# Password input
rpassword = "7"

Expand Down
3 changes: 3 additions & 0 deletions crates/clx-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ url.workspace = true
figment.workspace = true
async-trait = "0.1"
regex.workspace = true
shlex = { workspace = true }
# Codex project-trust reader parses the user-global Codex config.toml.
toml = { workspace = true }

# Per-project config trust (file-hash allowlist, §3.11). sha2/hex are already
# in the transitive graph; pin direct versions so we own the API surface.
Expand Down
2 changes: 1 addition & 1 deletion crates/clx-core/benches/recall_accuracy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ async fn evaluate(
.filter_map(|logical| seeded.id_map.get(logical).copied())
.collect();

let hits = engine.query(&pair.query, config).await;
let hits = engine.query(&pair.query, config).await.hits;
let retrieved: HashSet<i64> = hits.iter().map(|h| h.snapshot_id).collect();

let inter = retrieved.intersection(&expected_actual).count() as f64;
Expand Down
Loading
Loading