From 8945173e035fb344fd929d3ff1497825501dfc21 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Mon, 14 Sep 2026 11:31:16 -0600 Subject: [PATCH] build: upgrade KERIpy to the published 1.2.14 release Pin keri to 1.2.14 from PyPI and refresh its lockfile artifact. Retain hio 0.6.14, which satisfies the published KERIpy requirement of hio>=0.6.14. Reserve the existing KERIA Agent tock keys when resolving KERIpy cadences before Habery construction and reopening. Preserve legacy configuration without bypassing validation of KERIpy settings or dropping the tocks block. Test reopening with a checked-in legacy config file and real persisted Agent state, without patching LMDBer or Configer. Initial upgrade validation passed all 94 KERIA tests in Linux, Ruff checks, package builds, and CLI startup and shutdown. The revised real-file regression and two related configuration tests pass on macOS; the broader Agent run passes 22 tests with an existing fixed-identity collision reproduced in the original test. --- pyproject.toml | 2 +- src/keria/app/agenting.py | 39 +++++++++++++++- src/keria/testing/testing_helper.py | 8 +++- tests/app/test_agenting.py | 62 +++++++++++++++++++++++++ tests/scripts/keri/cf/legacy-tocks.json | 7 +++ uv.lock | 6 +-- 6 files changed, 118 insertions(+), 6 deletions(-) create mode 100755 tests/scripts/keri/cf/legacy-tocks.json diff --git a/pyproject.toml b/pyproject.toml index 22f4e2f6..490da66a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ keywords = [ requires-python = ">=3.12.2" dependencies = [ "hio==0.6.14", - "keri>=1.2.13,<1.3", + "keri==1.2.14", "mnemonic==0.21", "multicommand>=1.0.0", "falcon==4.0.2", diff --git a/src/keria/app/agenting.py b/src/keria/app/agenting.py index 1adc0423..b1bb07a9 100644 --- a/src/keria/app/agenting.py +++ b/src/keria/app/agenting.py @@ -39,6 +39,7 @@ querying, connecting, grouping, + tocking, ) from keri.app import delegating as kdelegating from keri.app.grouping import Counselor @@ -164,6 +165,32 @@ def readConfigFile(configDir: str, configFile: str, temp=False): ) +def keriTocks(cf): + """Resolve KERIpy cadences while reserving the existing KERIA Agent keys. + + Keep the config file intact so Agent can still read its legacy flat tocks. + Unknown keys and KERIpy values remain subject to KERIpy's validation. + """ + return tocking.resolveTocks( + cf.get().get("tocks") if cf is not None else None, + reserved=( + "signify", + "initer", + "querier", + "escrower", + "parser", + "witnesser", + "delegator", + "exchangeSender", + "granter", + "admitter", + "groupRequester", + "seeker", + "exchangecue", + ), + ) + + def runAgency(config: KERIAServerConfig, temp=False): """Runs a KERIA Agency with the given Doers by calling Doist.do(). Useful for testing.""" set_log_level(config.logLevel, logger) @@ -361,6 +388,7 @@ def create(self, caid, salt=None): bran=self.bran, ks=ks, cf=agent_cf, + tocks=keriTocks(agent_cf), temp=self.temp, salt=salt, ) @@ -441,8 +469,17 @@ def get(self, caid): ks = keeping.Keeper(name=caid, base=self.base, temp=self.temp, reopen=True) + cf = configing.Configer( + name=caid, base=self.base, temp=self.temp, reopen=True, clear=False + ) agentHby = habbing.Habery( - name=caid, base=self.base, bran=self.bran, ks=ks, temp=self.temp + name=caid, + base=self.base, + bran=self.bran, + ks=ks, + temp=self.temp, + cf=cf, + tocks=keriTocks(cf), ) agentHab = agentHby.habByName(f"agent-{caid}", ns="agent") diff --git a/src/keria/testing/testing_helper.py b/src/keria/testing/testing_helper.py index 0a56ee4b..03c021be 100644 --- a/src/keria/testing/testing_helper.py +++ b/src/keria/testing/testing_helper.py @@ -751,7 +751,13 @@ def openKeria(salter=None, cf=None, temp=True): ) agency = agenting.Agency(name="agency", bran=None, temp=True) - with habbing.openHby(name="keria", salt=salter.qb64, temp=temp, cf=cf) as hby: + with habbing.openHby( + name="keria", + salt=salter.qb64, + temp=temp, + cf=cf, + tocks=agenting.keriTocks(cf), + ) as hby: ims = eventing.messagize(serder, sigers=sigers) parsing.Parser(kvy=hby.kvy).parseOne(ims=ims) diff --git a/tests/app/test_agenting.py b/tests/app/test_agenting.py index bcebdd80..236b3e0c 100644 --- a/tests/app/test_agenting.py +++ b/tests/app/test_agenting.py @@ -34,6 +34,7 @@ from keria.app import agenting, aiding from keria.core import longrunning, httping +from keria.db import basing as agencybasing from keria.testing.testing_helper import SCRIPTS_DIR @@ -192,6 +193,67 @@ def test_load_ends(helpers): assert isinstance(end, agenting.ConfigResourceEnd) +def test_keri_tocks_preserves_agent_config(monkeypatch): + config = {"tocks": {"escrower": 1.0, "initer": 0.0, "receiptor": 0.25}} + with configing.openCF(temp=True) as cf: + cf.put(config) + monkeypatch.setenv("KERI_RECEIPTOR_TOCK", "0.125") + tocks = agenting.keriTocks(cf) + assert tocks["receiptor"] == 0.125 + assert "escrower" not in tocks + assert "initer" not in tocks + assert cf.get() == config + + cf.put({"tocks": {"escrower": 1.0, "receiptorTypo": 0.25}}) + with pytest.raises(kering.ConfigurationError, match="receiptorTypo"): + agenting.keriTocks(cf) + + +def test_agency_reopens_legacy_tocks(): + """Reload an evicted Agent from disk and retain its legacy tock settings.""" + caid = core.Signer().verfer.qb64 + with dbing.openLMDB(cls=agencybasing.AgencyBaser, temp=True) as adb: + cf = agenting.readConfigFile(SCRIPTS_DIR, "legacy-tocks") + agency = agenting.Agency(name="agency", bran=None, cf=cf, adb=adb) + doist = doing.Doist() + doist.enter(doers=[agency]) + # Provision the Agent and write its own config from the legacy fixture. + agent = agency.create(caid) + try: + assert agent.tocks["escrower"] == 1.0 + assert agent.hby.tocks["receiptor"] == 0.25 + persisted_config_path = agent.hby.cf.path + # Close the Agent's resources and evict it from the Agency cache, + # leaving its configuration and databases on disk for reopening. + agency.shut(agent) + assert caid not in agency.agents + + # This cache miss is the reopen: Agency.get constructs a new Agent + # from its persisted config and databases, rather than returning + # the previously cached instance or provisioning it again. + agent = agency.get(caid) + assert agent.hby.cf.path == persisted_config_path + assert agent.hby.cf.get()["tocks"] == cf.get()["tocks"] + assert agent.tocks["escrower"] == 1.0 + assert agent.hby.tocks["receiptor"] == 0.25 + finally: + agency.shut(agent) + doist.exit() + for resource in ( + agent.seeker, + agent.exnseeker, + agent.monitor.opr, + agent.notifier.noter, + agent.rep.mbx, + agent.rgy.reger, + agent.mgr.rb, + agent.hby, + agent.hby.cf, + ): + resource.close(clear=True) + cf.close() + + def test_load_tocks_config(helpers): with helpers.openKeria() as (agency, agent, app, client): agenting.loadEnds(app=app) diff --git a/tests/scripts/keri/cf/legacy-tocks.json b/tests/scripts/keri/cf/legacy-tocks.json new file mode 100755 index 00000000..731d3ced --- /dev/null +++ b/tests/scripts/keri/cf/legacy-tocks.json @@ -0,0 +1,7 @@ +{ + "tocks": { + "initer": 0.0, + "escrower": 1.0, + "receiptor": 0.25 + } +} diff --git a/uv.lock b/uv.lock index c192bc77..276d90e0 100644 --- a/uv.lock +++ b/uv.lock @@ -493,7 +493,7 @@ wheels = [ [[package]] name = "keri" -version = "1.2.13" +version = "1.2.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "apispec" }, @@ -517,7 +517,7 @@ dependencies = [ { name = "qrcode" }, { name = "semver" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/0f/6a7fd0cbd681c31fad385e2a5f27ac9ea9e6f7aae6f30b5814f960acdf17/keri-1.2.13.tar.gz", hash = "sha256:aef033ec3b17d4b04d8801b5365b225b6cba5630a67aaad2f306aaecbd256fcd", size = 479577, upload-time = "2026-05-06T18:24:47.865Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/c4/2d63280bb5d9599d9766d22db58a45ddd1fdb0fb12b839692a7a3a76b3c4/keri-1.2.14.tar.gz", hash = "sha256:f921a42794aa83988987f97d27337da38194dcd7fb0124511374112997660656", size = 494448, upload-time = "2026-09-09T15:28:06.354Z" } [[package]] name = "keria" @@ -555,7 +555,7 @@ requires-dist = [ { name = "falcon", specifier = "==4.0.2" }, { name = "hio", specifier = "==0.6.14" }, { name = "http-sfv", specifier = "==0.9.9" }, - { name = "keri", specifier = ">=1.2.13,<1.3" }, + { name = "keri", specifier = "==1.2.14" }, { name = "marshmallow-dataclass", specifier = "==8.7.1" }, { name = "mnemonic", specifier = "==0.21" }, { name = "multicommand", specifier = ">=1.0.0" },