diff --git a/CHANGELOG.md b/CHANGELOG.md index 36678a6ba..df10c4992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,15 +10,95 @@ installable release; see the roadmap in [README.md](README.md). ## [Unreleased] -### Changed +## [1.7.0] - 2026-05-07 + +Two structural changes drive v1.7.0: BM25F anchor-text retrieval flips default-on, and every ingest entry point now routes through a single `derivation_worker` that treats the append-only `ingest_log` as the source of truth. On top of that lands the v2.0 detector wave (dedup, semantic contradiction, value-comparison, sentiment-from-prose, wonder-consolidation), four new CLI verbs (`reason`, `wonder`, `confirm`, `delete`), the `unlock`/`promote` lock-management surface, and a wave of edge-type ship gates. -- **Differential CI gates for docs-only PRs** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). `ci.yml` (pytest matrix), `deadcode.yml` (deptry), and `codeql.yml` (analyze) now skip on PRs whose changed files are entirely under `docs/`, `**/*.md`, `LICENSE`, `.github/ISSUE_TEMPLATE/**`, or `.github/PULL_REQUEST_TEMPLATE.md`. Mixed PRs still run full CI. The `staging-gate` security checks (gitleaks, PII pattern-scan, history-scan, release-docs-check, commit-msg-prefix, pr-body-issue-link) and `typos` always run regardless of paths. Net effect: a single-file docs PR drops from ~3 min of CI to ~30s. CodeQL still runs full-tree weekly via the existing schedule. After branch protection lands at the public flip, the path-filter approach migrates to a `dorny/paths-filter` detection job so required checks always report a status. +The README roadmap row for v1.7 also lists signed-Laplacian (#149), heat-kernel authority (#150), Plate FFT HRR primitives (#216), and HRR bind/probe (#152). Those remain placeholder lanes in `[retrieval]` config — wiring did not land in this cut and they are not user-visible. The roadmap row is accurate that they "remain opt-in"; v1.7.0 in practice is the BM25F flip, the #264 worker refactor, and the items below. ### Added -- **PR-title conventional-commit prefix gate** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). New `pr-title-prefix` job in `staging-gate.yml` mirrors the existing `commit-msg-prefix` job but validates the PR title. Fails the PR if the title does not start with `feat:`, `fix:`, `docs:`, or another approved prefix. Prefix list is delegated to `scripts/check-commit-msg.py` so it stays in sync with commits and CLAUDE.md. Catches the silent failure mode where a missing `docs:` prefix disables CodeRabbit's `ignore_title_keywords` filter and runs unwanted bot review on a docs PR. +- **BM25F default-on; Porter stemming on the BM25F lane** ([#148](https://github.com/robotrocketscience/aelfrice/issues/148), [#154](https://github.com/robotrocketscience/aelfrice/issues/154)). BM25F anchor-text retrieval flips to default-on per the v1.7 retrieve_uplift bench evidence (`+0.6650 NDCG@k` uplift on the v0.1 fixture under Porter stemming). Lands the per-flag NDCG@k harness (`tests/retrieve_uplift_runner.py`) plus the no-regression bench-gate test that the operator can run lab-side against `AELFRICE_CORPUS_ROOT`. Porter stemming is added to the BM25F lane with an LRU memoised stem function for performance. Reversible via `[retrieval] use_bm25f_anchors = false` in `.aelfrice.toml` for users who want the v1.6 ranking back. Other v1.7 components (`use_signed_laplacian` #149, `use_heat_kernel` #150, `use_hrr_structural` #152) stay opt-in pending lane wiring. + +- **`aelf reason` + `aelf wonder` — graph-walk CLI surfaces** ([#389](https://github.com/robotrocketscience/aelfrice/issues/389), [#390](https://github.com/robotrocketscience/aelfrice/issues/390)). Two new walking surfaces over the belief graph. `aelf reason ` returns a chain of beliefs along graph edges that explains why the retrieval surfaced what it did; `aelf wonder` walks the speculative-belief frontier to surface phantom beliefs the consolidation pipeline has not yet promoted. Phantom scaffolding lands with `ORIGIN_SPECULATIVE` and a `Phantom` dataclass in `aelfrice.models`. Smoke tests, slash commands (`/aelf:reason`, `/aelf:wonder`), and a bench-gate harness with skip-on-no-corpus all ship. The MCP `aelf_confirm` tool (#390) provides the affirm-without-locking primitive that the wonder-consolidation pipeline uses to upgrade phantoms. + +- **`aelf confirm` — affirm a belief without locking it** ([#441](https://github.com/robotrocketscience/aelfrice/issues/441)). New CLI verb that bumps the Beta-Bernoulli posterior of an existing belief toward truth without freezing it. `aelf lock` is the right tool when you want a permanent rule; `aelf confirm` is the right tool when you want to say "yes, this is correct" without short-circuiting the decay machinery. Slash command `/aelf:confirm` and reference doc updates ship with it. Contributes to the posterior-ranking eval surface (#151). + +- **`aelf delete` — hard-delete with audit row** ([#440](https://github.com/robotrocketscience/aelfrice/issues/440)). New CLI verb that hard-deletes a belief from the store after writing an audit row. Confirmation prompt by default; `--yes` to skip; locked beliefs require `--force` (and still write the audit row). Slash command `/aelf:delete` and reference doc updates ship with it. Closes a long-standing surface gap: previously the only delete path was through `aelf doctor` cleanup flags, which made one-off lock cleanup awkward. + +- **`aelf unlock` + `aelf promote` — explicit lock-management surface** ([#391](https://github.com/robotrocketscience/aelfrice/issues/391)). `aelf unlock ` drops the user-lock on a belief without changing its origin, writing a `lock:unlock` audit row. `aelf promote ` upgrades an `agent_inferred` belief to `user_validated` origin. Both ship as CLI verbs, MCP tools (`aelf_unlock`, `aelf_promote`), and slash commands (`/aelf:unlock`, `/aelf:promote`). The existing `aelf demote` path is rerouted through `unlock()` for audit parity — every lock-drop now writes the same audit row regardless of which surface dropped it. + +- **`aelf health` — per-edge-type breakdown + `--json`** ([#452](https://github.com/robotrocketscience/aelfrice/issues/452)). `aelf health` gains an `edges_by_type` field on `HealthFeatures` and a per-edge-type breakdown block in the human-readable output. New `--json` flag emits the full feature struct as machine-readable JSON for scripting. Tests cover the populated case, the empty-graph path, and the JSON shape contract. + +- **`session_id` propagation — T3 close-out** ([#192](https://github.com/robotrocketscience/aelfrice/issues/192)). v1.6.0 wired `session_id` through onboard / scanner / MCP. T3 closes the remaining propagation gaps: a shared helper picks up `AELFRICE_SESSION_ID` from the environment as a fallback when no explicit session is passed; `ingest_turn`, `aelf lock --id`, and the MCP `tool_lock` entry point all honor it and stamp the column on inserted beliefs and on `ingest_log` / corroboration rows. Beliefs without a discernible session continue to land with `session_id = NULL`. The corroboration recorder (#190) and the deferred-feedback sweeper (#191) now have full session attribution across every ingest path. + +- **Selective L0 injection on `UserPromptSubmit`** ([#373](https://github.com/robotrocketscience/aelfrice/issues/373), [#199](https://github.com/robotrocketscience/aelfrice/issues/199) H3). New `top_k_locks` retrieval helper plus a `locked_max_k` knob on `retrieve()` enables top-k-of-locks selection on the per-prompt path. The `UserPromptSubmit` hook uses it to inject only the top-relevance locks (rather than all locks) when selective mode is active; `SessionStart` complements by suppressing the always-injected locked-baseline under selective mode so the two paths don't double-count. Covers the H3 ship gate from the v2.0 enforcement reading. _Subsumed in this same release by #379 below: the `locked_max_k` knob is removed and locks return to always-inject. The two issues land together because the H3 gate measurement is what drove the always-inject decision._ + +- **Edge-type-keyed rerank consumer + `POTENTIALLY_STALE` BFS skip** ([#421](https://github.com/robotrocketscience/aelfrice/issues/421)). Two halves: (1) `EDGE_POTENTIALLY_STALE` marker edge type ships in `aelfrice.models` and is pinned to `weight = 0.0` in the BFS multi-hop walk so stale-edged beliefs are skipped during expansion; (2) the new `aelfrice.edge_rerank.apply_edge_type_rerank` post-rerranks retrieval candidates by their incoming edge types via `MemoryStore.edges_to(dst)`. Multi-edge composition is multiplicative; same edge type firing multiple times collapses to one factor. Together with #387 below the contradiction surface now writes evidence and the retrieval surface respects it. + +- **`POTENTIALLY_STALE` edge writer (`aelf doctor --detect-stale`)** ([#387](https://github.com/robotrocketscience/aelfrice/issues/387)). Producer side of the rerank consumer (#421). New `aelf doctor --detect-stale` flag walks the relationship-detector output and writes `POTENTIALLY_STALE` edges from sub-confidence contradicts. Direction, idempotency, and report counts covered by `tests/test_relationship_detector_stale_writer.py`. + +- **Semantic contradiction detector v3 — typed-slot value-comparison gate** ([#422](https://github.com/robotrocketscience/aelfrice/issues/422)). v3 successor for the regex-based R2 detector closed `wontfix` at adversarial recall 0.033. Adds a typed-slot extractor (`aelfrice.value_compare`) that pulls numeric values, enumerated keys, and bounded vocabularies (e.g. `0.5` vs `1.0`, `indexed` vs `full table scan`, `synchronous` vs `async`) into a typed slot, plus a mutual-exclusion comparator that produces `contradicts` directly without needing token overlap. Wired into `relationship_detector` behind the `use_value_comparison` feature flag. Lab adversarial corpus bench-gate (`tests/bench_gate/test_contradiction_v3.py`) targets recall ≥ 0.5 with precision ≥ 0.7. Stdlib-only path; embedding option left to a follow-up issue. + +- **Semantic contradiction detector + `aelf doctor` relationships audit** ([#201](https://github.com/robotrocketscience/aelfrice/issues/201)). New `relationship_detector` module with a semantic-contradiction pass; CLI integration as `aelf doctor relationships`. Acceptance tests cover detector behavior and CLI dispatch. Synthetic corpus carve-out documented; contradiction labels reconciled with the v2_0 corpus convention. + +- **Dedup audit pass + `aelf doctor dedup` CLI** ([#197](https://github.com/robotrocketscience/aelfrice/issues/197) R1). Round-1 dedup ships: core algorithm with a configurable `[dedup]` config block, audit pass that surfaces near-duplicates without acting, and `aelf doctor dedup` CLI for one-shot operator runs. User surface and `LIMITATIONS.md` shrink documented at [`docs/dedup.md`](docs/dedup.md). + +- **Wonder-consolidation bake-off — three phantom-generation strategies** ([#228](https://github.com/robotrocketscience/aelfrice/issues/228)). Three candidate strategies for phantom-belief generation evaluated head-to-head on a synthetic corpus: bake-off runner, evaluator, and ship-decision memo recorded at [`docs/wonder_consolidation_R_final.md`](docs/wonder_consolidation_R_final.md). + +- **Sentiment-from-prose feedback detector** ([#193](https://github.com/robotrocketscience/aelfrice/issues/193)). Regex-based sentiment-from-prose detector emits implicit posterior-feedback signal from inbound prose. `aelf health` surfaces the enabled/disabled state. Privacy doc updated to call out the inbound prose inspection scope ([`docs/PRIVACY.md`](docs/PRIVACY.md)). + +- **Five new triple-extractor edge types — `IMPLEMENTS`, `TESTS`, `TEMPORAL_NEXT`, `RELATES_TO`, `DERIVED_FROM`** ([#383](https://github.com/robotrocketscience/aelfrice/issues/383), [#384](https://github.com/robotrocketscience/aelfrice/issues/384), [#385](https://github.com/robotrocketscience/aelfrice/issues/385), [#386](https://github.com/robotrocketscience/aelfrice/issues/386), [#388](https://github.com/robotrocketscience/aelfrice/issues/388)). Each lands on the same template: a new edge type in `aelfrice.models` with a tuned BFS weight (`IMPLEMENTS` 0.65, `TESTS` 0.55, `TEMPORAL_NEXT` 0.25, `RELATES_TO` per #383 corpus, `DERIVED_FROM` per #388), a triple-extractor verb pass that emits the edge from canonical verbs, and a per-type ship gate at +5pp BFS uplift on the `bfs_multihop` corpus. Edge-weight notes live in [`docs/bfs_multihop.md`](docs/bfs_multihop.md). + +- **Query-strategy router — R1 entity-expand + R3 IDF-clip** ([#291](https://github.com/robotrocketscience/aelfrice/issues/291)). New `query_understanding` modules implement R1 (entity-expand) and R3 (IDF-clip) query rewrites. The rebuild stage gains a `query_strategy` setting that routes between the legacy stack and the R1+R3 stack. Default remains legacy; opt-in via `[rebuild] query_strategy = "r1_r3"` for the new path. + +- **Rebuild-log instrumentation on `UserPromptSubmit`** ([#288](https://github.com/robotrocketscience/aelfrice/issues/288) phase-1a). The rebuild diagnostic log added in v1.6.0 gains coverage of the `UserPromptSubmit` hook path. Each per-prompt rebuild now appends a JSONL record; the audit script in `scripts/audit_rebuild_log.py` (also from v1.6.0) handles UPS records uniformly with the existing PreCompact records. + +- **Directive-detection — Path A intent-prefix filter** ([#374](https://github.com/robotrocketscience/aelfrice/issues/374), [#199](https://github.com/robotrocketscience/aelfrice/issues/199) H1). H1 ship of the v2.0 enforcement reading: a regex-based intent-prefix filter that detects directive-shaped input on `UserPromptSubmit`. Bench gate + candidate detector land first, then the prefix-filter behavior. Spec memo at [`docs/directive_detection.md`](docs/directive_detection.md). + +- **`uri_baki` post-rank score adjuster — N=10k/50k retest** ([#153](https://github.com/robotrocketscience/aelfrice/issues/153)). Post-rank score adjusters (URI-aware boost/dampen) reland with a retest harness at N=10k and N=50k. Experimental — opt-in via `[retrieval] use_uri_baki = true`. + +- **Replay-soak gate — consecutive-green streak computer + PR-time gate** ([#262](https://github.com/robotrocketscience/aelfrice/issues/262), [#403](https://github.com/robotrocketscience/aelfrice/issues/403)). Operationalises the v1.6.0 `replay_full_equality` probe as an actual CI signal: daily cron appends a status JSONL on a dedicated branch, `replay_soak_streak` computes the consecutive-green streak from that log, and a PR-time gate workflow (`replay-soak-gate.yml`) blocks merges that don't have a ≥7d green streak. Path-scoped to the derivation contract surface (`derivation.py`, `derivation_worker.py`, `replay.py`, `ingest.py`, `scanner.py`, soak fixture, soak workflows) so out-of-scope PRs aren't soak-gated. Hypothesis-based replay-equality probe (deliverable B) walks the `ingest_log` and asserts byte-equal store state across permuted inputs. `hypothesis` added to the dev dependency group. The check is currently advisory — adding it to `required_status_checks` is deferred until the streak is operationally satisfiable. + +- **End-to-end install/upgrade test matrix** ([#334](https://github.com/robotrocketscience/aelfrice/issues/334)). New `tests/e2e/` skeleton with five scenarios: install → onboard → search; hook inject roundtrip via the rebuild seam; source-kind discrimination across ingest paths; v1.4 → current migration roundtrip from a captured v1.4 snapshot fixture. Install scripts cover `uv tool install` / `pipx install` / `venv + pip` matrix. PR-label-opt-in workflow (`e2e` label) gates the e2e job in CI. + +- **Testing-strategy unit/integration/E2E split + `attn:e2e-failure` workflow** ([#370](https://github.com/robotrocketscience/aelfrice/issues/370)). Documents the unit / integration / E2E split at [`docs/testing-strategy.md`](docs/testing-strategy.md). E2E workflow triggers on `push:main` and opens an `attn:e2e-failure` issue if the suite fails — main-branch-only, so PRs aren't on the hook. + +- **Close-the-loop measurement harness — spec memo** ([#317](https://github.com/robotrocketscience/aelfrice/issues/317)). Spec memo at [`docs/close-the-loop.md`](docs/close-the-loop.md) for the close-the-loop measurement pipeline; implementation in a future cut. + +- **PR-title conventional-commit prefix gate** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). New `pr-title-prefix` job in `staging-gate.yml` mirrors the existing `commit-msg-prefix` job but validates the PR title. Fails the PR if the title does not start with `feat:`, `fix:`, `docs:`, or another approved prefix. Prefix list is delegated to `scripts/check-commit-msg.py` so it stays in sync with commits and CLAUDE.md. + +- **Auto-`docs` label for docs-only PRs** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). New `label-docs.yml` workflow inspects changed files via the API and applies (or removes) the `docs` label whenever the path set matches the docs-only globs. Mirrors the path filters in the heavy gates so the label is a faithful indicator of which PRs skipped pytest / deptry / CodeQL. + +### Changed + +- **Write-log-as-truth derivation worker — every ingest entry point routed through `derivation_worker`** ([#264](https://github.com/robotrocketscience/aelfrice/issues/264)). The largest internal refactor of v1.7.0 (19 commits across the cycle). The append-only `ingest_log` (introduced in v1.5) becomes the source of truth: every ingest entry point — `ingest_turn`, the regex scanner, the LLM-classifier `accept_classifications` path, the MCP `tool_lock`, the `triple_extractor` worker, and the `aelf lock` CLI verb — is rerouted through a single `aelfrice.derivation_worker` module that derives store state from the log. Each route ships with an integration test plus a per-route replay-equality gate that asserts a freshly-derived store from the log is byte-equal to the live store after the same operations. New `aelf doctor --derive-pending` flag sweeps any unstamped log rows from before the worker landed. `replay_full_equality` (introduced in v1.6) holds across every route. Behavior is unchanged at the public API; the refactor is the v2.0 prereq that lets the log replace the legacy mutation-on-write path. `LIMITATIONS.md` notes the worker-route re-derivation escape hatch for operators who need to rebuild from the log. + +- **Locks always inject — `locked_max_k` knob removed; locks treated as always-injected pool** ([#379](https://github.com/robotrocketscience/aelfrice/issues/379)). Reframes locks as the always-injected pool: every lock ships on every prompt, in full, regardless of relevance score. The `locked_max_k` knob added in #373 (selective L0) is removed from `retrieve()`, `search_for_prompt`, and the `UserPromptSubmit` hook; `SessionStart` always injects the full locked set. Lock count is now the user's baseline-context budget knob — if you've locked 200 things, every session opens with all 200, by your design. Mechanically simpler, easier to reason about, and removes the H3-gate decision path from the per-prompt critical path. Documented across [README.md](README.md), [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md), and [`docs/v2_enforcement.md`](docs/v2_enforcement.md). #373 and #379 land in the same release because the H3 measurement is what drove the always-inject decision. + +- **Update banner reword + `/aelf:upgrade` advisory rename** ([#427](https://github.com/robotrocketscience/aelfrice/issues/427)). The previous shape `"⬆ /aelf:upgrade to v1.6.0"` read as an imperative pointing at a slash command that is itself advisory. New shape embeds the install-method-aware command from `upgrade_advice()` directly: `"⬆ aelfrice 1.7.0 — run: uv tool upgrade aelfrice"`. Slash command renames `/aelf:upgrade` → `/aelf:upgrade-cmd`; `aelf upgrade` CLI subparser renames to `aelf upgrade-cmd` with `aelf upgrade` kept as a deprecated alias for one minor (emits a stderr deprecation notice on invocation). Existing user installs pick up the new slash file via the orphan-prune path in `aelf setup`. Reverses the v1.5.1 self-replacing upgrade introduced in #242: in practice users on `uv tool` and `pipx` setups preferred copy-paste authority over implicit self-replacement, especially after #345 surfaced multi-install machines. + +- **Per-lane relevance floor + silent-when-empty in rebuild** ([#364](https://github.com/robotrocketscience/aelfrice/issues/364)). The rebuild stage applies a per-lane relevance floor (locked / l25 / l1 / bfs each get their own threshold) and emits an empty block instead of a degraded one when no lane clears its floor. Lifts the noise floor on the rebuilt context — fewer borderline-relevance beliefs leak into the continuation when the retrieval signal is weak. + +- **CI workflow paths-filter migration** ([#446](https://github.com/robotrocketscience/aelfrice/issues/446)). Replaced workflow-level `paths-ignore` in `.github/workflows/ci.yml` with an in-job `dorny/paths-filter@v3` step. Pytest jobs now always run (so the `pytest (3.12)` / `pytest (3.13)` required status checks always report) but install + test steps short-circuit on docs-only PRs. Unblocks docs-only PRs under the `required_status_checks` ruleset on main. Migrates the TODO note from #413 to actual implementation. + +- **Differential CI gates for docs-only PRs** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). `ci.yml` (pytest matrix), `deadcode.yml` (deptry), and `codeql.yml` (analyze) now skip on PRs whose changed files are entirely under `docs/`, `**/*.md`, `LICENSE`, `.github/ISSUE_TEMPLATE/**`, or `.github/PULL_REQUEST_TEMPLATE.md`. Mixed PRs still run full CI. The `staging-gate` security checks (gitleaks, PII pattern-scan, history-scan, release-docs-check, commit-msg-prefix, pr-body-issue-link) and `typos` always run regardless of paths. Net effect: a single-file docs PR drops from ~3 min of CI to ~30s. CodeQL still runs full-tree weekly via the existing schedule. *(Subsumed for the pytest workflow by the #446 paths-filter migration above.)* + +- **Replay-soak status writes to dedicated branch; PR gate reads from it** ([#461](https://github.com/robotrocketscience/aelfrice/issues/461)). Refactors the #403 replay-soak status pipeline so the daily cron writes status JSONL to a dedicated branch and the PR gate reads from that branch. Removes the race where a PR could land on top of an in-flight cron status push. The 0-byte stub of `.replay-soak-status.json` left on `main` from the original #403 implementation is removed. + +- **README/ROADMAP/COMMANDS realignment for v1.5.1/v1.6.0/v1.7.0** ([#360](https://github.com/robotrocketscience/aelfrice/issues/360)). Sweep across [README.md](README.md), [`docs/ROADMAP.md`](docs/ROADMAP.md), [`docs/LIMITATIONS.md`](docs/LIMITATIONS.md), and [`docs/COMMANDS.md`](docs/COMMANDS.md) to reflect the post-v1.6.0 ship state — surface count, onboard default, budget defaults, posterior-ranking section. [`docs/CLI_SURFACE_AUDIT.md`](docs/CLI_SURFACE_AUDIT.md) marked as a v1.3-era historical memo. + +- **README quickstart no longer reads as a 4-step install**. The original quickstart bundled `aelf lock "never push directly to main; use scripts/publish.sh"` as the third of four lines, indistinguishable from a required step. Users ran the example verbatim and ended up with a permanent locked belief about a publish script that did not exist in their repo. The quickstart is split: install + setup + onboard are the install. The `aelf lock` example is now in its own block under "add your first rule", explicitly called out as an example to substitute or skip. `pip install` switched to `pipx install` (with `uv tool install` as alternative) — `aelf` is a global CLI, and `pip install` failed outright on PEP 668 systems and on macOS where no `pip` shim is on PATH. + +### Fixed + +- **`relationship_detector` id-collision corroboration guard in `insert_or_corroborate`** ([#264](https://github.com/robotrocketscience/aelfrice/issues/264)). Found during the worker-routing refactor: when two beliefs hash-collided on `content_hash` (rare but possible after heavy abbreviation), `insert_or_corroborate` could route the second insert to the wrong belief id and silently corroborate the wrong belief. New guard cross-checks the belief id before recording a corroboration; on collision, both inserts proceed independently. + +- **`override_belief_type` reconstructed from `raw_meta` on full-equality probe** ([#264](https://github.com/robotrocketscience/aelfrice/issues/264)). The replay-equality probe was failing on classification-route entries because `override_belief_type` was stored on the live row but not reconstructed from `raw_meta` when re-deriving. Fix reconstructs the field from the log payload so the probe holds across the classification route. + +- **lychee link-check — drop removed `--exclude-mail` flag** ([#414](https://github.com/robotrocketscience/aelfrice/issues/414)). Upstream lychee dropped the flag; CI workflow updated. -- **Auto-`docs` label for docs-only PRs** ([#413](https://github.com/robotrocketscience/aelfrice/issues/413)). New `label-docs.yml` workflow inspects changed files via the API and applies (or removes) the `docs` label whenever the path set matches the docs-only globs above. Mirrors the path filters in the heavy gates so the label is a faithful indicator of which PRs skipped pytest / deptry / CodeQL. +- **`flag-stale-open-prs` — refresh `origin/main` before `is-ancestor` check**. Workflow was running `git merge-base --is-ancestor` against a stale `origin/main` ref and falsely flagging fresh PRs as stale. ## [1.6.0] - 2026-05-02 @@ -597,7 +677,8 @@ Foundation milestone — store, models, config. - Initial repo scaffold: pyproject, README, GitHub Actions workflows, scan configs (commit `67b4343`). -[Unreleased]: https://github.com/robotrocketscience/aelfrice/compare/v1.6.0...HEAD +[Unreleased]: https://github.com/robotrocketscience/aelfrice/compare/v1.7.0...HEAD +[1.7.0]: https://github.com/robotrocketscience/aelfrice/compare/v1.6.0...v1.7.0 [1.6.0]: https://github.com/robotrocketscience/aelfrice/compare/v1.5.1...v1.6.0 [1.5.1]: https://github.com/robotrocketscience/aelfrice/compare/v1.5.0...v1.5.1 [1.5.0]: https://github.com/robotrocketscience/aelfrice/compare/v1.4.0...v1.5.0 diff --git a/README.md b/README.md index 8af8e7887..a08848618 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,20 @@ You correct your agent. *"Got it,"* it says. Next session, same mistake. aelfrice runs in the background and stops the forgetting. You write a rule once and it gets attached to every prompt thereafter — no cross-references for the agent to skip, no markdown files to maintain, nothing to remember to do. ```bash -pip install aelfrice -aelf onboard . +pipx install aelfrice # or: uv tool install aelfrice +aelf setup # wire the hook into your agent +aelf onboard . # scan the current project and ingest beliefs +``` + +Then add your first rule and restart your agent: + +```bash aelf lock "never push directly to main; use scripts/publish.sh" -aelf setup # wire the hook into Claude Code ``` -That's it. Restart Claude Code and your next prompt that mentions "push" already has the rule attached. From here on out aelfrice is invisible — no command to remember to run, no file to keep updated. +That's it. Your next prompt that mentions "push" already has the rule attached. From here on out aelfrice is invisible — no command to remember to run, no file to keep updated. + +> The `aelf lock` line above is an example — substitute your own rule. Skip it entirely if you'd rather start with onboarded beliefs only and add locks as you go. --- diff --git a/pyproject.toml b/pyproject.toml index 19f56a54c..0355f7011 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "aelfrice" -version = "1.6.0" +version = "1.7.0" description = "Persistent memory for AI agents. Set up once. Stays out of your way. Local SQLite, auditable, no GPU, no network." readme = "README.md" requires-python = ">=3.12" diff --git a/uv.lock b/uv.lock index 37ae60a1c..4a432ae84 100644 --- a/uv.lock +++ b/uv.lock @@ -12,7 +12,7 @@ resolution-markers = [ [[package]] name = "aelfrice" -version = "1.6.0" +version = "1.7.0" source = { editable = "." } dependencies = [ { name = "numpy" },