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
135 changes: 133 additions & 2 deletions CHANGELOG/v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,129 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [3.5.0] - 2026-06-04

The visibility / observability wave. Every belief-write surface gained a
read-side counterpart: a per-project event log (#931), a SessionStart
recap that points at it (#934), a contradiction marker on `aelf search`
(#938), an L1 listing that mirrors `aelf locked` (#937), a stale-by-age
listing (#933), a cross-store dedup audit against the host's auto-memory
(#935), and a markdown-edited weekly review checkpoint (#936). Plus a
PreToolUse:Bash guard that catches duplicate `gh issue create` calls
before they land (#941), and a statusline that surfaces L0/L1/`?` counts
(#932).

### Added

- **`.aelfrice-feed.jsonl` per-project belief-write log + `aelf feed`
reader (#931).** Append-only JSONL row per write event across all five
write paths (lock / onboard / wonder-promote / feedback / ingested).
Write-side errors are swallowed so a feed failure can't break the
write path that triggered it. Rotates at 100 MB. Reader supports `--since`
filtering and a JSONL passthrough mode. Default-on, opt-out via
`AELFRICE_FEED_LOG=0`.
- **`aelf stale` subcommand — surface beliefs by age + retrieval
recency (#933).** Deterministic threshold-based listing over
`created_at` + `last_retrieved_at`; no decay model, no relevance
score. `--older-than DAYS` + `--cold-for DAYS` + `--locked-only` +
`--json` + `--limit`. Sort order: never-retrieved first, then oldest
cold, then oldest creation. SQLite p95 ≤50 ms on a 10k-belief fixture
via the existing `idx_beliefs_origin_created` index.
- **SessionStart belief-write recap injection (#934).** After the
locked-baseline block, the SessionStart hook counts feed-log rows
newer than the previous SessionStart timestamp (persisted in
`<db-dir>/sessionstart_last.txt`). If the count meets the threshold,
one fixed-template line is injected: `aelfrice: N beliefs written
since last session — \`aelf:feed -n N\` to review.` Below threshold:
nothing. Threshold default 3, override via
`AELFRICE_SESSIONSTART_RECAP_THRESHOLD`; opt-out via
`AELFRICE_SESSIONSTART_RECAP=0` (also discoverable as
`aelf setup --no-sessionstart-recap`). Default-on. All recap-side
errors are caught and swallowed so the SessionStart contract is
preserved even if the feed log is missing or unreadable.
- **`aelf audit-claude-memory` cross-store dedup audit (#935).** New
subcommand that compares locked aelfrice beliefs against the host
harness's auto-memory store at
`<host-dir>/projects/<encoded-path>/memory/MEMORY.md` and emits a
four-bucket report (`duplicates`, `contradictions`, `aelfrice_only`,
`claude_only`). Pure read-only — never writes to either store, never
auto-promotes / auto-locks. Reuses the `value_compare.SlotConflict`
primitive; rows that don't tokenise cleanly are skipped silently
rather than producing false-positive matches.
- **Weekly belief-review workflow — `aelf review --generate` /
`aelf review --apply` (#936).** Phase A. Generates
`.aelfrice/review.md` with the 10 oldest-retrieved-but-unconfirmed
beliefs as a markdown checkbox file; the user edits at their cadence
ticking `keep` / `remove` / `lock` boxes; `aelf review --apply` parses
the file and dispatches verdicts. Apply is fail-closed:
`AmbiguousRowError` (>1 checked box) and `MalformedRowError` (missing
belief ID) raise immediately without applying any partial state. New
`last_confirmed_at` column on the belief table (NULL = never
confirmed); the candidate sorter treats NULL as oldest. Phase B (the
`aelf:stale --excludes-recent-confirms` integration) ships separately
on a follow-up PR.
- **`aelf speculative` subcommand — list non-user-locked (L1) beliefs
(#937).** Read-only mirror of `aelf locked`. Lists every active
belief with `lock_level = 'none'`, sorted by α descending, grouped by
origin tag. `--origin TAG` filters; `--limit N` truncates (positive
integer required — SQLite treats negative LIMIT as uncapped); `--json`
emits one JSON object per line. No promote / lock affordance in the
output by design (#605 PHILOSOPHY).
- **`[!]` contradiction-flag column on `aelf search` (#938).** New
`AELF_SHOW_CONFLICTS=1` env var. When set, hits whose value-slots
collide (exact-slot equality, different objects) with any locked
belief's slots get a `[!]` marker; in `--json` mode the row gains a
`slot_conflict_with: <locked_id>` field. Zero false positives by
construction — slot-equality is a hard match. Latency p95 ≤2 ms added
per query (locked set pre-extracted once per invocation). Default-off
because the surface adds visual noise to every search result.
- **Statusline L0/L1/`?` count badges (#932).** Surfaces locked
(`L0=N`), speculative (`L1=N`), and contradiction (`?=N`) counts in
the `aelf statusline` block so users see the store's shape at a
glance.
- **`aelf-pre-issue-hook` PreToolUse:Bash duplicate-detection guard
(#941).** Fires when the host harness is about to execute a Bash
command starting with `gh issue create`. Extracts `--title`,
tokenises (strips conventional-commit prefix, lowercases, drops
stop-words), runs `gh issue list --search` and `git log --grep` in
parallel, and BLOCKs (exit 2) when any candidate scores ≥0.5 on
Jaccard. Catches the dup-of-shipped trap structurally — same gap
`aelf-pr-open.sh` closes on the PR side. Default-on, opt-out via
`AELFRICE_NO_PRE_ISSUE_GUARD=1` or `aelf setup --no-pre-issue-guard`;
emergency bypass via `ALLOW_DUP_ISSUE=1`. `--body-file` paths
resolving under the host's `~/.claude/` are refused at read time.

### Fixed

- **`aelf setup` refuses worktree-pathed venv in hook resolvers
(#928).** Hook command resolution now rejects venv paths that contain
worktree-specific segments (e.g. `.claude/worktrees/<id>/`), which
would otherwise be hard-coded into `settings.json` and break for any
session run outside that worktree.

### Documentation

- **Full docs audit + factual correction sweep (#923).** 55-file pass
across `docs/`, `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md`,
`SECURITY.md`, `CODE_OF_CONDUCT.md`, all 21 slash command docs,
benchmarks/tests READMEs, and the PR template. Propagates v3.1 #814
contradict-auto-demote removal across READMEs, propagates v3.0.1 #730
uv-only install collapse across QUICKSTART / CONFIG / MCP /
LIMITATIONS / COMMANDS, fixes `slash_commands/reason.md`'s wrong
`aelf feedback` signal, brings COMMANDS.md / SLASH_COMMANDS.md in
sync with the actual CLI surface (adds `aelf graph`, `aelf scope-out`,
`aelf export-canvas`, `aelf export-obsidian`, `aelf cadence-score`,
`aelf label`).
- **README + ROADMAP `stack-r1-r3` p99 latency reconcile (#925).**
Both surfaces now use the delta-over-legacy framing the gate test at
`tests/bench_gate/test_query_strategy.py` actually enforces, instead
of the prior absolute / "% of 5 ms budget" claims that didn't match
the contract.

## [3.4.0] - 2026-05-26

The cadence-policy completion + conversation-aware retrieval wave.

### Added

- **`p3_substantive` cadence policy is now wired live (#876).** The
Expand Down Expand Up @@ -41,7 +164,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
— no operator-week of real shadow data required. Each fixture tick is
fed through every `would_fire` predicate; the rows aggregate through
the same `compute_summary`. Deterministic (#605), no live state, no
`~/.claude/` content. A sample fixture ships at
host-directory content. A sample fixture ships at
`benchmarks/fixtures/cadence_replay_sample.json`.

### Fixed
Expand All @@ -57,6 +180,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`[user_prompt_submit_hook] conversation_aware_query_enabled`; window
and weight are tunable. Deterministic, no embeddings.

> **Note.** v3.4.0 was never tagged as a standalone release; its
> changelog body originally lived under `[Unreleased]` while PR #924
> sat open. The body is preserved here for historical accuracy. The
> v3.5.0 cut on 2026-06-04 ships every commit under both this section
> and `[3.5.0]` above in a single PyPI publish.

## [3.3.0] - 2026-05-21

### Added
Expand Down Expand Up @@ -342,7 +471,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **`urllib3` 2.6.3 → 2.7.0 for CVE patches** ([#640](https://github.com/robotrocketscience/aelfrice/issues/640)). Lockfile-only dependency bump pulled in via `uv lock` to clear two CVEs flagged by GitHub's dependency scanner. `urllib3` is a transitive dep (via `requests` in the publish workflow and the `gh` CLI's Python shim); aelfrice itself does not import it. No source change.

[Unreleased]: https://github.com/robotrocketscience/aelfrice/compare/v3.3.0...HEAD
[Unreleased]: https://github.com/robotrocketscience/aelfrice/compare/v3.5.0...HEAD
[3.5.0]: https://github.com/robotrocketscience/aelfrice/compare/v3.3.0...v3.5.0
[3.4.0]: https://github.com/robotrocketscience/aelfrice/compare/v3.3.0...v3.5.0
[3.3.0]: https://github.com/robotrocketscience/aelfrice/compare/v3.2.0...v3.3.0
[3.2.0]: https://github.com/robotrocketscience/aelfrice/compare/v3.1.0...v3.2.0
[3.1.0]: https://github.com/robotrocketscience/aelfrice/compare/v3.0.1...v3.1.0
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "aelfrice"
version = "3.3.0"
version = "3.5.0"
description = "Persistent memory for AI coding agents. Local SQLite + UserPromptSubmit hook — matched beliefs in the prompt before the model sees it. Deterministic, auditable, no embeddings, no cloud."
readme = "README.md"
requires-python = ">=3.12"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

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

Loading