Repository navigation
Release v0.23.0 - #699
Merged
Merged
Release v0.23.0#699
Conversation
Moves the six version sites to 0.23.0, dates the seven changelog entries that sat under Unreleased, adds the release notes in their pending state and records the release candidate in the control documents. v0.22.0 stays the latest published release. Nothing here tags, publishes or dispatches anything. The changelog entries lose the "Unreleased (on main, not in v0.22.0)" prefix and move under the dated v0.23.0 heading. Two wordings change beyond the prefix: the revocation event of the keys entry and the legacy memory history tool of the malformed id entry no longer carry the word the repository keeps out of its text, and a sentence break in the malformed id entry is fixed. The new test file test_v0230_release_notes.py pins the notes and runs their claims against this tree and against an export of the v0.22.0 tag. The tests that index the changelog by position move down one section, and the v0.22.0 notes test no longer reads the version sites, which belong to the new test. Forty-five cases of the mutation manifest are re-pinned (43 on CHANGELOG.md, 2 on CURRENT_STATE.md).
The real-host workflow test lists every test file that imports one of the host modules among the paths that start the heavy job. The notes test started the hook with a line that imported the hook module, so unit shard 1 failed on that list. The test now runs the hook with python -m, as a host's hook command does, and imports nothing from the host modules.
…e v0.23.0 notes test The flags test now names the flags of keys, keys create, keys list and keys revoke instead of checking only that those four commands are the ones that changed. The keyless refusal of the legacy tools is tested with the two legacy tools that resolve no agent identity of their own, so the refusal in call_mcp_tool is the only thing that stops them. A new test runs the helper that decides the environment values install writes on five payloads, in the v0.22.0 export and in this tree, and finds them equal.
… the docs Name labels, sources and project among the commands that run as the owner, fix the sleep-proposals name in the agent guide, and say there that an unbound admin_agent key does not get the evidence of an archived source. Keep the legacy tool name in the malformed id entry, say the recall cost was measured against the code before the change, and drop an import sentence no test covers.
Shard 2 reached 19 to 20 minutes as a job against its 20 minute limit, past the 17 minute split line, after the bench began minting each team key with its own alice-memory keys create process. The vectors bench file moves to shard 1 and the bench file to shard 5. Re-pin the seven mutation cases that cite the workflow file.
samrusani
marked this pull request as ready for review
October 30, 2026 15:54
This was referenced Oct 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release prep for v0.23.0, a minor release on v0.22.0. It moves every version site to 0.23.0, dates the seven changelog entries that sit under Unreleased, adds the notes in their pending state and records the release candidate in the control documents. v0.22.0 stays the latest published release, and nothing here tags, publishes or dispatches anything.
What v0.23.0 contains (
git log --first-parent v0.22.0..origin/main, merged at739507ed):alice-memory keys create,keys listandkeys revoke; once a vault holds an active key, an MCP call withoutALICE_AGENT_API_KEYis refused (the legacy tools too), andalice-memory briefand the session-start hook share one rule (run as the key's agent from their own environment, or print nothing and exit 0). A vault with no active key behaves as v0.22.0.alice_recallreturns ten note passages by default in passage and vectors mode, where it returned eight.POST /v0/vnext/open-loops/extractanswers 404 for a person that is not stored and makes no duplicate loop for another spelling;POST /v0/vnext/context-packsreturns the pack when a memory's source id is in a reference spelling; thirteen Alembic files complete for the documented self-hosted database owner.alice-memory import-markdownis faster on SQLite and stores the same result.25 files under
apps/api/srcdiffer from v0.22.0 (all modified, none added) and 13 underapps/api/alembic. No tool is added (default 3, full 12, legacy 74 and 77), no setting is added (no newALICE_name anywhere underapps/api/src), the only new command isalice-memory keyswithcreate,listandrevoke, and no migration is added: the head is20261011_0097as in v0.22.0. Thirteen migration files changed in place.What moved
scripts/release_check.pyrequires:pyproject.toml,apps/web/package.json,packaging/mcpb/manifest.json,plugins/alice-memory/.claude-plugin/plugin.json, and the two command pins inplugins/alice-memory/.mcp.jsonandplugins/alice-memory/hooks/hooks.json. Every other0.22.0stays, because it names the latest published release, the baseline, the checksums or the marketplace pin (refv0.22.0, commita6a5f49e).Unreleased (on main, not in v0.22.0):entries lose the prefix (the first word is capitalised) and move under the dated v0.23.0 heading (2026-10-30, in the formrelease_check.pyrequires), with an empty## Unreleasedabove it. Three wording edits beyond the prefix: the keys entry called an event by a word the repository keeps out of its text and now says "the revocation event"; the malformed id entry named a legacy tool whose name carries that word and now says "the legacy tool that returns a memory's history"; and a sentence break in the malformed id entry ("error. and the write actions") is now a comma. The import entry is as merged, including its measurement conditions.Unreleased (on main, not in v0.22.0),On main, not in v0.22.0,not in v0.22.0) finds onlyCHANGELOG.md: the seven entries at lines 5 to 11 of main, listed here by their first words: "the SQLite vault gets agent keys", "the MCP toolalice_recallreturns ten", "a vNext door that reads a row id", "POST /v0/vnext/open-loops/extract", "POST /v0/vnext/context-packsand the MCP tool", "the Alembic migrations20260510_0067", "alice-memory import-markdownon a SQLite vault". No document carried the form without the word Unreleased this time, so none moved to a "From v0.23.0" wording.docs/release/v0.23.0-release-notes.md, 14.6 KB, statependingandpending, no checksums file. Sections: What to do after upgrading, Agent keys on the SQLite vault, Server errors that are now answers, Migrations for the self-hosted database owner, Recall and import on SQLite, Other changes in the package, Behaviour changes an integrator will notice, Security, What this release does not claim, Install.docs/vnext/README.mdgain "v0.23.0is the current release candidate. It is not published." and keep v0.22.0 as the latest published release.CURRENT_STATE.mdgets a "Whatv0.23.0Targets" section above "Whatv0.22.0Shipped".docs/alpha/known-limitations.mdis unchanged, as it was in the v0.22.0 release PR (its header says v0.22.0, which is right until the post-publication change).Tests
tests/unit/test_v0230_release_notes.py, 29 tests, modelled on the v0.22.0 notes test at the release PR. It imports nothing that CI's environment lacks (no setuptools; the package walk is written out, and the file passes withsetuptools,pkg_resourcesandwheelhidden), and it starts the hook withpython -m, because a test file that imports a host module has to be listed in the real-host workflow's path filter (unit shard 1 failed on that in the first run; the second commit fixes it). Each test names its mutations in its docstring. Guards:20261011_0097; the budget 10 and the limit 8; the import numbers equal in the changelog entry and the notes; no hardware in the notes);NO FORCE ROW LEVEL SECURITY); the settings (no newALICE_name) and the flags of every command (onlykeysand its three sub-commands, flag by flag);installwrites the same environment values; the package holds nothing fromscripts/orapps/web;test_v0200_release_notes.py,test_v0202_release_notes.py,test_v0210_release_notes.py,test_v0211_release_notes.py,test_data_dir_guard.py,test_mcp_readonly_hints.py,test_claude_code_plugin.py), andtest_v0220_release_notes.pymoves its heading test and no longer reads the version sites, which belong to the new test (its version test is renamedtest_the_marketplace_pins_the_published_release_and_the_notes_carry_its_install_lines, and its release check test runs the pre-tag rule for0.22.0explicitly), as Release v0.22.0 #681 did for v0.21.1.be9b0f33, an exact single-match replace or a created or deleted file, the named test green first, the file written back from saved bytes). 74 ontest_v0230_release_notes.py(one of them fails two tests), and 6 on the edited older tests: three changelog shape mutations (the v0.23.0 heading redated, the v0.22.0 heading renamed, a section inserted between them), each failing all 8 position tests, and three on the edited v0.22.0 tests (marketplacerefback to v0.21.1, the install line in its notes, its status set to pending). The 74 cover: title, state, checksums file, section list; plugin pin, package version, marketplacerefandsha, the install line; a candidate line gone from ROADMAP and README, v0.23.0 named latest published, the Targets section renamed; an entry under Unreleased, the heading redated, the old marker in an entry and in a doc; a dash, the disclosure verb, the review clause, an advisory identifier; the keys sentence reworded twice, a tenant word, the refusal called a fix; an upgrade step renamed, the hook environment clause, a limits clause, the known-difference sentence; two numbers of the notes, a hardware word, the budget, the limit, a tool added to the default surface, a migration file added, an unlisted migration changed,NO FORCEtaken out of 0067, a revision renamed; a newALICE_name, a flag added tokeys list,keys revokerenamed,scriptsadded to the packages and toMANIFEST.in, an install key reference; the raw key printed twice, a hash in the list record, the not-shown-again line dropped,--projectbinding nothing, the reserved name, a blank project and a blank agent id allowed; the keyless call let through, revoked keys counted, a legacy tool let through, an unreadable key table let through, the brief and the hook without a key (three),import-chatgptasking for a key, a hash in the creation event, an archived source let through to a key; the budget back to 8, an explicit limit ignored, the budget in document mode,alice_explainreading the id as sent; the integration file deleted, a sentence of the errors section, the comparison page, the comparison link; four changelog entry mutations; a published status.scripts/derived_label_mutations.json:lineandsha256refreshed on the 45 edits that nameCHANGELOG.md(43) andCURRENT_STATE.md(2); nobeforetext failed to resolve. All 45 cases were replayed withscripts/verify_derived_label_mutations.py --only NAME --output DIRagainst headbe9b0f33(45 names, 45 results): 45 of 45 killed by the test they name, baseline exit 0 and mutant exit 1 for each.test_derived_label_mutation_manifest_matches_tree.pypasses.Claim checks
Every sentence of the notes that states a behaviour was run against this branch and against an export of the v0.22.0 tag (
git archive v0.22.0), each with its ownPYTHONPATH, through the real entry points:alice-memorycommands,alice-memory mcpover stdio (JSON-RPCtools/call), the session-start hook withecho '{}'on stdin and a timeout, and, for the PostgreSQL doors, the mounted ASGI application against the local PostgreSQL 16 (a fresh database per test). No other host was contacted. Verdicts below are v0.22.0 then this branch.keys createprints the raw key oncekeys create --agent-id claude-code --profile admin_agent --label "Claude Code host"on a fresh vaultinvalid_request, no outputalice_sk_...), line 2 "Store this key now; it is not shown again, and only its sha256 hash is stored.", line 3 agent, profile, label--projectbinds; same refusals as the PostgreSQL command--project acme;~global; blank; blank agent id; profilenonsenseproject=acme); the other four exit 2 with "the project name ~global is reserved by Alice ...", "project_scope must not be blank", "agent_id is required", and the generic invalid request for the profile (argparse choices)keys listshows no hash and no raw key--json, grep for the key and its sha256keys revokealice_recallandalice_capture(full tools) with noALICE_AGENT_API_KEY, a key mintedcreate_agent_key)not_permitted, "The tool request could not be processed", for bothALICE_MCP_LEGACY_TOOLS=1andALICE_MCP_FULL_TOOLS=1not_foundfor an unknown id)not_permitted; the repository test usesalice_open_loop_extractandalice_graph_neighborhood, which resolve no identity of their ownnot_permittedfor a bad keynot_permitted; revoking the last active key makes a keyless call answer againrevoked_atcolumn of the key table, call keylessnot_permittedalice-memory briefon the keyed vault, no keyalice-memory-session-start,{}on stdin, JSON and markdowndoctor,export,sleep,sleep-proposals,import-markdown,import-chatgpt,import,keys liston the keyed vault, no keyPRAGMA wal_checkpoint(TRUNCATE), copymemory.dbsources delete, thenalice_explain,alice_memory_review,alice_context_packas the keyless owner and as an unboundadmin_agentkeyalice_explainrefused ("requested explanation is unavailable"), review and pack carry no source id; owner: all three carry it (explain 11,088 bytes, review 5,187, pack 2,175 against 4,637 and 1,859 for the key)alicebot agent keys createwithsqlite:///andsqlite:////URLs on a vault with 2 keys; callers ofcreate_agent_key; the record typesimportacceptsinvalid_request, key count 2 before and aftercreate_agent_keyiscli/agents.py;importtakes no key record; no MCP tool mints. No advisory, as the brief saidalice_recallreturns ten passages, not eightalice_recallwith no limitALICE_SEARCH_QUALITY=offALICE_SEARCH_QUALITY=vectors, opt-in on, loopback endpoint that records every text, 15 chunks embeddedvectors)vectors); with limit 8 it is 8alice_explainfinds a memory by another spelling of its id (SQLite)urn:uuid:, braces, no hyphens;no-such-idnot_foundfor all five;not_foundnot_foundGET /v0/vnext/beliefs/no-such-id/state,POST .../open-loops/no-such-id/review,GET .../projects/no-such-id/dashboard,POST .../projects/update-candidates/no-such-id/reviewInvalidTextRepresentation), 500, 500, 409open-loops/extractscope.person_idof no row;no-such-personForeignKeyViolationonopen_loops_person_fkey); 500 (InvalidTextRepresentation)not_found; 404not_foundcontext-packssource_idisurn:uuid:,URN:UUID:,source:,uuid:oralice://sources/InvalidTextRepresentation) for all fivetests/integration/test_malformed_id_doors_postgres.py,test_open_loop_person_not_found_postgres.py,test_source_id_spelling_context_pack_postgres.pycopied into the tag exporttest_migrations_forced_flags_restore.pyNotNullViolationonrevision_numberofmemory_revisionsat 0067, onconfig_fingerprint_sha256ofmodel_providersat 0088); the flags file fails on collection: 5 of 13 bracketedScriptDirectory.get_heads(); a byte comparison of both Alembic folders20261011_0097, 98 revisions20261011_0097, 98 revisions; 13 files differ, none added or removed, each gainedNO FORCE ROW LEVEL SECURITYupgrade head; and a fresh upgrade with this code20261011_0097before and after; schema fingerprint (columns, row-level security flags, 156 policies, indexes, triggers)02abcaaacffe54b6before and after, and the same after a fresh upgrade: 105 tables, 96 forcedimport-markdownscripts/generate_markdown_perf_corpus.py --seed 5, one credential file, two duplicates), fresh vaults, 17 tables compared with ids and timestamps set asideembedding_stamp.token(random) andevent_log.integrity_hash(covers ids and timestamps) differ; 202 sources, 1,570 chunks; dry run receipts equalEXPLAIN QUERY PLANof the lookupsources_user_captured_idxsources_user_content_hash_idxinstalltakes the same flags and writes the same valuesinstall --helpmd5;_own_envon 5 payloads--agent-key-envis not a flagkeysis newALICE_name; the parser of every commandkeys,keys create,keys list,keys revokeonlypython -m build --no-isolationof the head,git archivecopyscripts/orapps/webin eitherFindings of the check, handled in the notes or left alone:
docs/alpha/mcp-tools.mdsays only that an archived source's quote is withheld from every key. The notes state it in the words above and the checks above reproduce it, and v0.22.0 gives a key the same answers. Adding it toknown-limitations.mdwould be its own change (five tests pin that page).alice-memory install --agent-key-env VARNAMEexists. It does not on main. No parser has the flag, and_own_envinhost_install.pycarries a docstring about "the agent key's environment reference" with no code behind it. The changelog and the notes say only that install writes no key and no flag takes one. The docstring is stale and was left alone (a source change).docs/alpha/agent-integration.mdnames the commandproposals. It issleep-proposals. The notes use the real name.Validation
Run on head
be9b0f33in a worktree of the repository, with the repository's own Python 3.12.11 andPYTHONPATHset to the worktree'sapps/api/srcand root.python scripts/release_check.pyand with--require-finalized-release-docs:Release check: PASS (alice-memory 0.23.0)for both.python scripts/check_control_doc_truth.py: PASS (16 documents verified).python scripts/check_commit_authors.py --base origin/main --head HEAD: PASS (3 commits).scripts/check_protected_paths.pycategorization of the changed files (25 atbe9b0f33, 27 ate65e67a6): no protected area is touched.python -m ruff check apps/api/src/alicebot_api scripts tests eval/longmemeval: all checks passed.python -m mypy --ignore-missing-importswith the file list of the CI step: no issues in 295 source files.python -m compileall -qon the three folders of the CI step: clean.tests.yml, each aspython -m pytest <selection> -q -p no:cacheprovider, the five in parallel, from a clean tree with the logs outside it:test_[p-r]*,test_saved_p*,test_[t-w]*): 6,028 passed, 0 failed, 2 skippedtest_[0-9a-c]*,test_s[!aoq]*,test_saved_quotes_*): 4,249 passed, 0 failed, 11 skippedtest_[j-o]*,test_s[oq]*): 15,038 passed, 0 failed, 23 skippedtest_saved_quote_*): 488 passed, 0 failedtest_[d-i]*): 2,736 passed, 0 failed, 4 skippedpytest eval/longmemeval -q: 218 passed.be9b0f33.make release-check, the web tests, the real-host jobs and thepublish-recheck-rehearsal.ymlrun itself. CI runs the required ones, and the rehearsal is dispatched on the merge commit before the tag.Not fixed here
docs/alpha/known-limitations.mdstill says v0.22.0 as the release it describes; it moves in the post-publication change.agent-integration.md,mcp-tools.md,backup-and-restore.md,known-limitations.md,SECURITY.md) carry no "From v0.23.0" marker._own_envdocstring and the--agent-key-envsentence of Agent keys on the SQLite vault #698, above.unit shard 1has one live-server test,test_request_body_limits.py::test_a_live_server_refuses_a_flood_closes_the_connection_and_keeps_serving[chunked], that failed once with "Connection reset by peer" while mutation runs shared the machine; it passed alone three times and in the final shard run.What is left for after publication
The same mechanical change as after v0.22.0: add
docs/release/v0.23.0-checksums.txtand set the notes state topublishedandrecorded; move the statements that name the latest published release, the baseline and the checksums to v0.23.0 (README, ARCHITECTURE, PRODUCT_BRIEF, ROADMAP, RELEASING, CURRENT_STATE,docs/vnext/README.md) and drop the candidate lines; move the marketplacerefandshato the v0.23.0 tag commit and the sentences that name the v0.22.0 pin; move the install and checkout lines; add the v0.23.0 notes and changelog section totest_published_release_notes_stay_immutable.py; turn the pending-state tests oftest_v0230_release_notes.pyinto the published form; refreshlineandsha256in the manifest.Commits after be9b0f3
3ef3a7f9Complete the owner command list and state the admin key difference in the docs:labels,sourcesandprojecttoo. Run on a keyed vault with noALICE_AGENT_API_KEY:labels check,sources list,project reportandproject showexit 0, whilebriefprints 0 bytes.docs/alpha/agent-integration.mdnamessleep-proposals(it saidproposals, which is not a command), lists the same owner commands, and states the known difference next to the advice to mint an unboundadmin_agentkey for the owner's hosts. The notes' "What this release does not claim" calls it one exception rather than the only one, since a keyed explain also carries policy decision rows.alice_vnext_memory_auditas it is on main; the test that keeps the word out of the entry now looks only at text outside code spans.5d277e9fRe-pin the mutation cases whose files changed: 44 edits (43 citingCHANGELOG.mdfor its digest, 1 citingdocs/alpha/agent-integration.md, line 404 to 408). Replayed all 44 against local PostgreSQL 16: 44 killed, 44 baselines green.Checks on
5d277e9f:release_check.pyplain and--require-finalized-release-docsPASS;check_commit_authors.py --base mainPASS (5 commits);ruff checkclean;test_v0230_release_notes.py,test_phase5_enterprise_handoff_truth.pyand the manifest test 50 passed, 1 skipped; the 15 doc test files that readagent-integration.mdplustest_sqlite_agent_keys.pypassed. Mutations of the edited tests, each alone: droplabelsfrom the step (the upgrade steps test fails), restore "the exception above" (the limits test fails), put the word in the entry's prose (the changelog entry test fails).e65e67a6Move the showcase bench tests out of unit shard 2. CI on5d277e9fcancelled "Unit tests, shard 2 of 5" at its 20 minute limit with 98 percent of the shard run, and main's own run on739507eddid the same. Shard 2 took 16 minutes as a job before the agent keys change and 19 to 20 after it (it passed at 19:14 and 19:48 on that change's heads), past the 17 minute split line ingates.json. Run locally on3e95d082and739507ed, shard 2 went from 413 s to 496 s of tests, almost all in three files:test_showcase_bench_vectors.py16 to 72 s,test_showcase_bench.py51 to 68 s andtest_alice_bench_ranking_mode.py5 to 15 s, because the bench now starts onealice-memory keys createprocess per team key. Local shard totals on739507ed: 1 317 s, 2 496 s, 3 351 s, 4 337 s, 5 205 s. The vectors bench file moves to shard 1 and the bench file to shard 5; shard 2 dropstest_sh*from itsspattern and keeps the other showcase files withtest_showcase_[!b]*.py.test_ci_unit_job_split.pyand every unit test that reads the workflow pass (352 passed, 1 skipped); dropping the bench file from shard 5, or giving shard 2 back its oldspattern, fails the split test. The seven mutation cases that cite the workflow were re-pinned and replayed: 7 killed, 7 baselines green.Upgrade Overview
Protected Areas
None is touched.
scripts/check_protected_paths.pycategorizes none of the 27 changed files. The changes are version strings, documentation, tests, the mutation manifest and the unit shard selection in.github/workflows/tests.yml.Compatibility Impact
No code change in this PR. The code v0.23.0 ships is the code on main. The package version moves from 0.22.0 to 0.23.0, and the MCPB manifest and the Claude Code plugin pins move with it. The marketplace file still pins the v0.22.0 tag commit until the post-publication change.
Migration / Rollout
No migration is added. PostgreSQL stays at revision
20261011_0097; thirteen existing migration files changed in place (see the notes) and a database already at or past them is not touched. A SQLite vault with no key behaves as in v0.22.0; once a key is minted, each agent host needsALICE_AGENT_API_KEYin its MCP server environment and in the launch environment of the session-start hook. Tagging, the release gate, the rehearsal run and publication are not part of this PR.Operator Action
None for this PR. Before the tag, dispatch
publish-recheck-rehearsal.ymlon the merge commit and confirm its run is on the SHA to be tagged.Validation
scripts/release_check.py(with and without--require-finalized-release-docs),scripts/check_control_doc_truth.py,scripts/check_commit_authors.py, the protected-path categorization,ruff check, the CImypystep, the five unit shard selections oftests.yml,pytest eval/longmemeval, the eight PostgreSQL integration files, the 80 mutations and the manifest replays above.Rollback
Revert the merge commit. Nothing is tagged or published by this PR, so there is no external state to undo.