Repository navigation
[Fellowship Challenge] Expiring memory (ttl.v1) for the memory layer - #295
Open
Prathmesh010190 wants to merge 2 commits into
Open
Prathmesh010190 wants to merge 2 commits into
Prathmesh010190 wants to merge 2 commits into
Conversation
This branch has not been deployed
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.
Submission for the Hexaware x Project NANDA Fellowship Technical Challenge
Summary
This PR adds expiring memory to the memory layer (layer 10):
memory: ttl.v1, a plugin that stops serving a remembered entry once its time limit has passed. It comes with a negative-control plugin (ttl_off.v1), a new Lab scenario (marketplace_expiring_memory), a validator for it, and tests.The gap
The default memory plugin,
kv.v1, never forgets. In the marketplace scenario, the buyer rememberspreferred_sellerafter round one, and in round two it quotes only that seller instead of looking up sellers again through the registry. Nothing in the layer can mark a remembered fact as stale, so an agent can keep acting on old knowledge for as long as the run lasts.What I added (layer: memory)
ttl.v1(src/nandatown/layers/memory_ttl.py): a subclass ofKeyValueMemory.rememberstores the value askv.v1does. If the agent's scenario config declares a limit for that key (memory_ttl: {preferred_seller: 0.5}), it also storesexpires_at = engine.now + limitand putsexpires_atin thememory_writtenevent.recallreturns the value as before if the key has no limit. If a limit exists andengine.now >= expires_at, it deletes the entry, emitsmemory_expired(key andexpires_at), and returnsNone. Otherwise it emitsmemory_recalledand returns the value.ttl_off.v1(same file): the negative control. It recordsexpires_atand emitsmemory_recalledwith"stale": true, but still returns the expired entry.marketplace_expiring_memory(src/nandatown/sim/scenarios/): a copy of the marketplace scenario withmemory: ttl.v1andmemory_ttl: {preferred_seller: 0.5}onbuyer-1. The duplicate-delivery fault stays in the scenario.src/nandatown/sim/validators.py), a label for the newmemory_expirystage (report.py), tests (tests/test_memory_ttl.py), and the scenario name added toALL_SCENARIOSintests/test_sim.py.memory_ttlto the import list insrc/nandatown/layers/__init__.py.I did not change
sim/agents.pyorsim/api.py.Design decisions
expires_atwith the engine's logical clock (engine.now), not wall-clock time, so the run stays seeded andverifycan reproduce it.memory_expiredevent shows onlykeyandexpires_at.memory_ttlbehaves exactly likekv.v1.memory_ttlfrom the agent's entry inengine.spec.agents.memory_reusestage. With expiry, round two looks sellers up again, so there is a 4th request and no reuse. My validator accepts at least 3 quote requests fordiscovery, dropsmemory_reuse, and addsmemory_expiry.Fault and invariant
Fault: the remembered entry ages past its limit between rounds.
preferred_selleris written at t=1.90 with a limit of 0.5 (soexpires_atis about 2.40), and round two reads it at t=2.90. The duplicate-delivery fault still runs alongside it.Invariant (
memory_expirystage):memory_recalledevent has"stale": true(an entry past its expiry was served).memory_expiredevent exists, because then the rule was never exercised.With
ttl.v1, the read at t=2.90 emitsmemory_expired(ev-43) and the buyer looks sellers up again. That run has 70 events and 4 quote requests. All eight stages pass.Negative control
nandatown run marketplace_expiring_memory --layer memory=ttl_off.v1fails. The first broken stage ismemory_expiry("the buyer recalled a memory entry after its expiry time"). The replay showsmemory_recalledwith"stale": trueat t=2.90 as ev-43, the same event number that ismemory_expiredin the passing run. The failing run has 66 events and 3 quote requests, and every other stage still passes. So the failure comes from the memory rule alone, which is the reason I predicted.Evidence
nandatown verifyprinted "bundle verified: hashes match and the evaluator reproduces the recorded result" on all four bundles below.ttl.v1sim-1a4bfd88f4e1ttl_off.v1memory_expirysim-d3ba949c7a7ettl.v1(later rerun)sim-ade7e723796fttl_off.v1(later rerun)memory_expirysim-d883966bd119The first pair has bundle fingerprints
sha256:a0969f51...efd(passing) andsha256:a00ce6f3...fbb(failing). The rerun gave the same verdicts, but different bundle fingerprints. I did not investigate why.Tests (
tests/test_memory_ttl.py, 4 tests):memory_expirypasses and amemory_expiredevent exists).Fail before, pass after: with
src/nandatown/layers/__init__.pyandsrc/nandatown/sim/validators.pyreverted toorigin/main, all 4 tests fail. With my versions restored, all 4 pass.Full suite on this branch: 1760 passed, 1 skipped, 0 failed.
How to reproduce
The
runs/folder is not committed. I can attach the bundles if reviewers want them.What this does not prove
seller-beither way, so expiry does not change who gets paid. The evidence shows that an expired entry is never served and the buyer looks sellers up again.discoverycheck. My validator accepts at least 3 quote requests, where the stock one requires exactly 3.What I would do next