Skip to content

fix(memory): stage() mirrors manual lessons into AGENT_LEARNINGS.jsonl#57

Open
diazMelgarejo wants to merge 2 commits into
codejunkie99:masterfrom
diazMelgarejo:atomic-01-episodic-mirror-fix
Open

fix(memory): stage() mirrors manual lessons into AGENT_LEARNINGS.jsonl#57
diazMelgarejo wants to merge 2 commits into
codejunkie99:masterfrom
diazMelgarejo:atomic-01-episodic-mirror-fix

Conversation

@diazMelgarejo

@diazMelgarejo diazMelgarejo commented Jul 17, 2026

Copy link
Copy Markdown

Atomic PR 01 of 3

Summary

stage()'s manual-lesson path writes a candidate with evidence_ids: [now], promising an episodic record exists at that timestamp in AGENT_LEARNINGS.jsonl — but never writes one. The auto-derived candidate path mirrors correctly; the manual path doesn't. Result: a graduated lesson's evidence_ids can point at a timestamp with no matching episodic record.

Fix

Adds _append_episodic_mirror(), called right after the candidate file is written, using the same timestamp so evidence_ids[0] always resolves.

Fail-open on OSError — a mirror-write failure never blocks staging.
Minimal, additive, stdlib-only.

Verification

  • Applied cleanly to master @ 00eda65c, syntax-checked.
  • Isolated functional test: stage() now writes exactly one episodic mirror whose timestamp equals the candidate's evidence_ids[0].
  • 3 unit tests (see commit 2, kept separate — see below), all passing.
  • Found and fixed downstream in Perpetua-Tools, which vendors this project (vendor/agentic-stack). Validated there in two ways: 3 unit tests, and 6 real, non-test invocations of the fixed learn.py — all 6 evidence_ids verified programmatically to resolve to exactly one matching episodic record. Both are on PT main, commits 95f047f (fix) and 61dee0d (real-world validation), if useful cross-reference.

Two commits, intentionally separate

  1. fix(memory): ... — the fix alone.
  2. test(memory): ... — a standalone unittest (no pytest or other third-party dependency, since this project doesn't currently ship a test harness). Kept as a separate commit specifically so you can cherry-pick it out if you'd rather merge the fix without introducing the project's first test file this way.

Question for you: would you like the test included as-is, dropped, or adapted to a different location/convention? Fully open to whatever fits this project, this is offered as a starting point, not a requirement.

Background check

Searched open/closed issues and PRs for episodic, evidence_ids, mirror, no duplicate report. (#13 is a related-but-different gap: adapters not auto-populating the episodic log at all; this fix is about the manual-stage path specifically not mirroring.)

Note on this PR and its siblings

This is PR 1 of 3 prepared together as a small, related set (each stacked on the previous: #2 will be based on this branch, #3 on #2), separated so each can be reviewed and merged on its own merit, but designed as a set. (My own personal working patch on top of your latest release!)

Opening this one first; happy to hold 2 and 3 until this lands, or just open them now for visibility from my end, and mentioned here for transparency rather than surprising you with a queue later on. They can also all land together, whichever you prefer.

Thank you,

ALL THE BEST!

P.S.: your 0.19 draft spec looks exciting 💪🏼


Note

Mirror manual stage() calls into AGENT_LEARNINGS.jsonl as episodic records

  • Adds _append_episodic_mirror in learn.py that writes a JSONL entry to memory/episodic/AGENT_LEARNINGS.jsonl whenever a lesson is manually staged, using the same timestamp as the candidate file.
  • The mirror record includes action manual-stage:{cid}, pain score, importance, confidence, and evidence IDs linking back to the candidate.
  • Write failures are silently suppressed (fail-open) so staging is never blocked by a mirror write error.
  • Adds unit tests in test_learn_episodic_mirror.py covering one-record output, evidence ID resolution, and fail-open behavior.

Macroscope summarized a3d5139.

The manual-stage path in .agent/tools/learn.py writes a candidate with
evidence_ids: [now], promising an episodic record exists at that timestamp —
but never writes one. The auto-derived candidate path mirrors to
AGENT_LEARNINGS.jsonl correctly; the manual path does not. The result is a
referential-integrity gap: a graduated lesson's evidence_ids points at a
timestamp with no matching episodic record.

Fix: add _append_episodic_mirror(), called right after the candidate file is
written, using the same 'now' timestamp so evidence_ids[0] always resolves.
Fail-open on OSError so a mirror-write failure never blocks staging.

Minimal and additive — stdlib only, no new dependencies, no change to the
auto-derived path.

Found and fixed downstream in Perpetua-Tools (which vendors this project);
contributing back per that project's dogfooding practice.
Standalone stdlib unittest (no third-party test dependency) since this
project currently ships no test harness — intended as the first test file.

Kept as a SEPARATE commit from the fix so it can be cherry-picked out if the
maintainer prefers to merge the fix alone. Adapted from the downstream
Perpetua-Tools suite that proved this fix.

Covers: stage() writes exactly one matching episodic mirror; the candidate's
evidence_ids[0] resolves to exactly one episodic record (the regression this
targets); and _append_episodic_mirror fails open on write error.

Run: python3 -m unittest .agent/tools/test_learn_episodic_mirror.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant