memory: comprehensive week retrospective -- PT/orama collab Lessons - #317
Conversation
…ssons, blow by blow 9-part, evidence-grounded account of this week's actual incidents, not filtered for brevity: the orama<->PT sync policy documented then quietly violated; CVE-2025-30066 caught by verification discipline (and a third-party source's SHA found wrong by checking the real repo directly); CI workflow consolidation cascading into 3 more real bugs; the mv-into-existing-directory trap nearly dismissed as a bad test before being traced to ground; git am vs rebase state confusion; the append-only memory rule written then immediately violated by its own author, caught by external review; this session's own doctrine work getting the simple-vs-advanced hierarchy backwards, corrected by direct human instruction; and a consolidated list of recurring tooling/API gotchas that kept costing time even after individual capture. Closes with Part 9: what this is actually about -- judgment developed in one session surviving into the next in a form an agent can act on, not a transcript a human has to re-explain every time. The repeated 'never assume, never guess, always ask' instruction restated as what it actually is: not a lack of trust in capability, but a response to the specific, real gap this document traces between an agent's confidence a task is complete and the task actually being complete. 2 new durable lessons extracted (the other incidents already had individual lessons captured earlier this week, checked before adding anything to avoid re-graduating the same claim twice): - lesson_718c9430f44b: resolving real doctrine overlap correctly means sizing each document to its actual audience, not defaulting the newer/ simpler one to subordinate. - lesson_2d53056e593c: several gotchas recurred even after individual capture -- a checklist consulted before the relevant operation, not recall alone, is what actually prevents repetition. 966 lessons.jsonl lines, zero duplicate IDs. Both lessons' episodic mirrors confirmed. Hygiene clean. Retrospective doc: 0 markdownlint issues (fixed 5 duplicate-heading violations by making each part's sub-heading unique, not by suppressing the check).
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe changes add a collaboration retrospective, accepted memory records, episodic snapshots, Markdown lint settings, and filtering for legacy episodic rows during memory loading. ChangesAgent memory and episodic loading
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Critical bug scan — no issues found
Scope: 1 commit (de9fd0b6), 6 files (+695): week retrospective working doc, 2 graduated lesson JSON, episodic/semantic memory append, LESSONS.md render sync. No executable code changed.
Reviewed: Full diff (63551b23..de9fd0b6); traced incidents cited in the retrospective against current main guard/CI paths (atomic_append_snippet directory guard, endpoint-policy contract, git am detection) — all already landed in prior PRs (#251, #310, #314).
Validation:
lessons.jsonl: 966 rows, 0 duplicate IDs, append-only (+2, −0)AGENT_LEARNINGS.jsonl: 623→625 rows, prefix preserved (append-only)- Graduated JSON + all touched JSONL: 0 parse errors
recall.py "doctrine overlap sizing"surfaces new lessons correctlyrepo_hygiene.pyPASS
Verdict: No critical bugs. No fix PR opened.
Non-critical (not blocking): lesson_a8f3c2e91d04 backfilled into LESSONS.md alongside 2 new lessons — expected render catch-up; hand-edit vs render_lessons.py pipeline is process hygiene only.
Sent by Cursor Automation: Find critical bugs
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.agent/memory/semantic/lessons.jsonl (1)
965-966: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winReduce
conditionsto applicability triggers.
conditionscontains nearly every token from eachclaim. It includes generic words and the fragment"doesn". This differs from the focused conditions on Line 964. If lesson retrieval uses this field, the records can match unrelated contexts and reduce selection precision. Replace each list with a small set of scenario-specific triggers.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.agent/memory/semantic/lessons.jsonl around lines 965 - 966, Update the conditions arrays for lesson_718c9430f44b and lesson_2d53056e593c to contain only a small set of scenario-specific applicability triggers, removing generic claim tokens and fragments such as "doesn". Preserve the existing claims and all other lesson metadata unchanged, using focused terms that represent when each lesson should be retrieved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agent/memory/semantic/lessons.jsonl:
- Around line 965-966: Create tracked evidence JSON files under
.agent/memory/working for the two accepted lessons, using filenames or
identifiers that match evidence_ids 2026-08-01T06:53:43.608740+00:00 and
2026-08-01T06:53:43.671436+00:00. Ensure the files preserve resolvable
provenance for lesson_718c9430f44b and lesson_2d53056e593c without changing
their evidence_ids.
---
Nitpick comments:
In @.agent/memory/semantic/lessons.jsonl:
- Around line 965-966: Update the conditions arrays for lesson_718c9430f44b and
lesson_2d53056e593c to contain only a small set of scenario-specific
applicability triggers, removing generic claim tokens and fragments such as
"doesn". Preserve the existing claims and all other lesson metadata unchanged,
using focused terms that represent when each lesson should be retrieved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: bd8ee910-6cbf-404a-b486-2affc63ac9ab
📒 Files selected for processing (6)
.agent/memory/candidates/graduated/2d53056e593c.json.agent/memory/candidates/graduated/718c9430f44b.json.agent/memory/episodic/AGENT_LEARNINGS.jsonl.agent/memory/semantic/LESSONS.md.agent/memory/semantic/lessons.jsonl.agent/memory/working/2026-07-31-week-retrospective-pt-orama-collaboration-lessons.md
| {"id": "lesson_718c9430f44b", "claim": "When resolving real overlap between a new draft and an existing, more comprehensive doctrine, \"avoid duplication\" does not automatically mean \"make the newer, simpler thing subordinate to the older, more complex one.\" It means determining which document actually serves which situation and sizing each to its own job. A heavyweight protocol built for a rare, hard problem (e.g. concurrent multi-agent edits to the same repo, or reconciling a fork separated from its source by months of drift) should not become the default an agent reads first for the common, simple case (one branch, one agent, no concurrent editing) just because it existed first and is more thorough. Getting this backwards is not caught by re-reading a project's own stated single-source-of-truth value, since that value is genuinely being honored in some sense (no literal duplication) even while the sizing is wrong -- it may require direct correction from a human collaborator who can see the actual audience mismatch.", "conditions": ["actual", "actually", "agent", "audience", "automatically", "avoid", "backwards", "because", "become", "between", "branch", "built", "case", "caught", "collaborator", "common", "complex", "comprehensive", "concurrent", "correction", "default", "determining", "direct", "doctrine", "document", "draft", "drift", "duplication", "each", "editing", "edits", "even", "existed", "existing", "first", "fork", "genuinely", "getting", "hard", "heavyweight", "honored", "human", "job", "just", "literal", "make", "mean", "means", "mismatch", "months", "more", "multi-agent", "new", "newer", "older", "one", "overlap", "own", "problem", "project", "protocol", "rare", "re-reading", "reads", "real", "reconciling", "repo", "require", "resolving", "same", "see", "sense", "separated", "serves", "simple", "simpler", "since", "single-source-of-truth", "situation", "sizing", "some", "source", "stated", "subordinate", "thing", "thorough", "value", "which", "while", "who", "wrong"], "evidence_ids": ["2026-08-01T06:53:43.608740+00:00"], "status": "accepted", "accepted_at": "2026-08-01T06:53:50.451027+00:00", "reviewer": "host-agent", "rationale": "The hierarchy-inversion mistake this session, requiring direct human correction rather than self-catching -- worth a durable lesson about resolving overlap correctly, not just avoiding literal duplication.", "cluster_size": 1, "canonical_salience": 8.0, "confidence": 0.6, "support_count": 0, "contradiction_count": 0, "supersedes": null, "source_candidate": "718c9430f44b"} | ||
| {"id": "lesson_2d53056e593c", "claim": "Several tooling and API gotchas recur across a working session even after being individually caught once, because a single encounter doesn't automatically generalize into a standing rule: the PR-list API's merged field being unreliable (must check the single-PR endpoint); squash-merged branches never showing as git ancestors (verify by content/ID presence, not ancestry); a stale local checkout after an earlier push in the same session diverging silently; and diff-scoped CI lint checking a whole touched file, not just the changed hunk. Each of these needs to be treated as a standing checklist item to consult before the relevant operation, not a one-off lesson learned and then re-derived from scratch the next time it's encountered.", "conditions": ["across", "after", "ancestors", "ancestry", "api", "automatically", "because", "before", "branches", "caught", "changed", "check", "checking", "checklist", "checkout", "consult", "content", "diff-scoped", "diverging", "doesn", "each", "earlier", "encounter", "encountered", "endpoint", "even", "field", "file", "generalize", "git", "gotchas", "hunk", "individually", "into", "item", "just", "learned", "lesson", "lint", "local", "merged", "needs", "never", "next", "once", "one-off", "operation", "pr-list", "presence", "push", "re-derived", "recur", "relevant", "rule", "same", "scratch", "session", "several", "showing", "silently", "single", "single-pr", "squash-merged", "stale", "standing", "time", "tooling", "touched", "treated", "unreliable", "verify", "whole", "working"], "evidence_ids": ["2026-08-01T06:53:43.671436+00:00"], "status": "accepted", "accepted_at": "2026-08-01T06:53:50.615591+00:00", "reviewer": "host-agent", "rationale": "Several gotchas recurred even after individual capture -- worth the meta-lesson that a checklist consulted before the operation, not recall alone, is what actually prevents repetition.", "cluster_size": 1, "canonical_salience": 8.0, "confidence": 0.6, "support_count": 0, "contradiction_count": 0, "supersedes": null, "source_candidate": "2d53056e593c"} |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python - <<'PY'
import json
from pathlib import Path
semantic_path = Path(".agent/memory/semantic/lessons.jsonl")
episodic_path = Path(".agent/memory/episodic/AGENT_LEARNINGS.jsonl")
rendered_path = Path(".agent/memory/semantic/LESSONS.md")
retrospective_path = Path(
".agent/memory/working/2026-07-31-week-retrospective-pt-orama-collaboration-lessons.md"
)
expected = {
"lesson_718c9430f44b": {
"candidate": "718c9430f44b",
"evidence": "2026-08-01T06:53:43.608740+00:00",
},
"lesson_2d53056e593c": {
"candidate": "2d53056e593c",
"evidence": "2026-08-01T06:53:43.671436+00:00",
},
}
def load_jsonl(path):
return [
json.loads(line)
for line in path.read_text(encoding="utf-8").splitlines()
if line.strip()
]
semantic = {record["id"]: record for record in load_jsonl(semantic_path)}
episodic = load_jsonl(episodic_path)
retrospective = retrospective_path.read_text(encoding="utf-8")
rendered = rendered_path.read_text(encoding="utf-8")
for lesson_id, metadata in expected.items():
record = semantic[lesson_id]
assert record["status"] == "accepted"
assert record["source_candidate"] == metadata["candidate"]
candidate_path = Path(
".agent/memory/candidates/graduated"
) / f"{metadata['candidate']}.json"
assert candidate_path.is_file(), candidate_path
assert metadata["candidate"] in candidate_path.read_text(encoding="utf-8")
assert metadata["evidence"] in retrospective
assert any(
entry.get("id") == lesson_id
and entry.get("claim") == record["claim"]
for entry in episodic
)
assert lesson_id in rendered
print("Cross-layer lesson references and mirrors verified.")
PYRepository: diazMelgarejo/Perpetua-Tools
Length of output: 255
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import json
from pathlib import Path
semantic_path = Path(".agent/memory/semantic/lessons.jsonl")
assert semantic_path.is_file()
def load_jsonl(path):
return [
json.loads(line)
for line in path.read_text(encoding="utf-8").splitlines()
if line.strip()
]
semantic = {record["id"]: record for record in load_jsonl(semantic_path)}
for lesson_id in ("lesson_718c9430f44b", "lesson_2d53056e593c"):
record = semantic.get(lesson_id)
if record is None:
print(f"MISSING_semantic_{lesson_id}")
continue
print(f"\n--- {lesson_id} ---")
print(f"source_candidate={record.get('source_candidate')}")
print(f"status={record.get('status')}")
print(f"evidence_ids={record.get('evidence_ids')}")
candidate = record.get("source_candidate")
candidate_path = Path(".agent/memory/candidates/graduated") / f"{candidate}.json"
print(f"graduated_candidate_exists={candidate_path.is_file()}")
if candidate_path.is_file():
text = candidate_path.read_text(encoding="utf-8")
print(f"candidate_mentions_source_id={candidate in text}")
for key in ("id", "claim"):
print(f"{key}_in_candidate={key in text}")
for evidence in record.get("evidence_ids", []):
print(f"\n--- evidence link {evidence} ---")
evidence_path = Path(".agent/memory/working") / f"{evidence}.json"
print(f"evidence_json_exists={evidence_path.is_file()}")
if evidence_path.is_file():
ev = json.loads(evidence_path.read_text(encoding="utf-8", errors="replace"))
print(f"target_path={ev.get('target_path')}")
print(f"event_path={ev.get('event_path')}")
print(f"timestamp_keys={sorted(k for k in ev.keys() if 'time' in k.lower())}")
PY
echo
echo "--- tracked candidate and semantic metadata files ---"
git ls-files ".agent/memory/candidates/graduated/718c*".json ".agent/memory/candidates/graduated/2d53*.json" ".agent/memory/semantic/lessons.jsonl" ".agent/memory/working/2026-08-01T06:53:43.608740+00:00.json" ".agent/memory/working/2026-08-01T06:53:43.697436+00:00.json" ".agent/memory/episodic/AGENT_LEARNINGS.jsonl" ".agent/memory/semantic/LESSONS.md" | sortRepository: diazMelgarejo/Perpetua-Tools
Length of output: 1081
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import glob
from pathlib import Path
evidence_ids = [
"2026-08-01T06:53:43.608740+00:00",
"2026-08-01T06:53:43.671436+00:00",
"2026-08-01 06:53:43.608740 UTC",
"2026-08-01 06:53:43.671436 UTC",
"2026-08-01T06:53:43.608740",
"2026-08-01T06:53:43.671436",
]
working = Path(".agent/memory/working")
candidates_graduated = Path(".agent/memory/candidates/graduated")
print("exact working name matches:")
for iid in evidence_ids:
candidates = []
path = working / f"{iid}.json"
if path.is_file():
candidates.append(str(path))
print(f"{iid}: {candidates}")
print("\nworking files near evidence ids:")
base = "2026-08-01T06:53:43"
for p in sorted(working.glob(f"{base}*")):
print(p)
if p.is_file():
try:
import json
data = json.loads(p.read_text(encoding="utf-8", errors="replace"))
except Exception:
data = None
print(f" first_250: {(p.read_text(encoding='utf-8', errors='replace')[:250]).strip()}")
print(f" event_path_in_text={str(data.get('event_path')) if data else None}")
print(f" event_path_string_in_text={data.get('event_path') in p.read_text(encoding='utf-8', errors='replace') if data else None}")
print(f"\ngraduated files matching 2d/718 near timestamps:")
for p in sorted(candidates_graduated.glob("2d53*")) + sorted(candidates_graduated.glob("718c*")):
text = p.read_text(encoding="utf-8", errors="replace")
print(p)
for token in evidence_ids:
print(f" contains {token}: {token in text}")
import json
data = json.loads(text)
print(f" first_event_paths: {data.get('event_paths', [])[:5]}")
print(f" evidence_ids: {data.get('evidence_ids', [])[:5]}")
print("\nsearch tracked files:")
import subprocess
proc = subprocess.run(
["grep", "-R", "--files-with-matches", "-F", "2026-08-01T07:52:19", "."],
capture_output=True, text=True
)
print(proc.stdout or "<no matches>")
PY
echo
echo "--- file metadata for targeted JSONL lines ---"
wc -l .agent/memory/semantic/lessons.jsonl .agent/memory/episodic/AGENT_LEARNINGS.jsonl .agent/memory/semantic/LESSONS.md .agent/memory/candidates/graduated/718c9430f44b.json .agent/memory/candidates/graduated/2d53056e593c.jsonRepository: diazMelgarejo/Perpetua-Tools
Length of output: 1680
Add matching evidence JSON files for the accepted lessons.
Both source candidates exist, but the evidence_ids timestamps in .agent/memory/semantic/lessons.jsonl do not correspond to tracked .agent/memory/working/*.json files. Keep the evidence references valid so the semantic lessons retain resolvable provenance.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agent/memory/semantic/lessons.jsonl around lines 965 - 966, Create tracked
evidence JSON files under .agent/memory/working for the two accepted lessons,
using filenames or identifiers that match evidence_ids
2026-08-01T06:53:43.608740+00:00 and 2026-08-01T06:53:43.671436+00:00. Ensure
the files preserve resolvable provenance for lesson_718c9430f44b and
lesson_2d53056e593c without changing their evidence_ids.
…lint line, dream cycle .markdownlint-cli2.jsonc: same working exemption as orama-system -- verified overrides isn't a real config key, used the actual ignores mechanism instead, verified SKILL.md is skipped while other files (docs/LESSONS.md) still get checked normally. Retrospective doc: real cross-repo links throughout, added while verifying each one against the live repos (via gh, now authenticated) -- including finding and correcting a real inaccuracy: PT PR #314, which this document originally implied had merged, is actually closed without merging, confirmed by both ancestry and content checks. orama's sibling PR (#251) for the same fix did merge, so PT and orama are currently out of sync on exactly the review this document's Part 5 describes fixing -- flagged prominently in the Evidence Index, not silently corrected. Dream cycle (auto_dream.py): 154 patterns clustered, 0 new candidates (manual capture this week already comprehensive), 4 stale artifacts archived, 621 episodic entries retained. 621 episodic lines valid. Hygiene clean.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.agent/memory/episodic/AGENT_LEARNINGS.jsonl (1)
476-616: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winRemove the duplicate AGENT_LEARNINGS block before merging.
.agent/memory/episodic/AGENT_LEARNINGS.jsonlcontains 135 exact duplicate lines, including the legacy daily-summary row at lines 1 and 476. The only correction entry points at an unmatchedsupersedeshash, so it does not identify the legacy duplicate. Keep the intended append-only correction/lessons, but remove the duplicate span so the memory ledger is not polluted with replayed rows.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl around lines 476 - 616, Remove the duplicated AGENT_LEARNINGS record block from the episodic ledger, including the repeated legacy daily-summary entry and its associated replayed rows, while preserving the original block and all intentional correction/lesson entries. Verify the remaining JSONL has no duplicate lines and retains valid append-only ordering; do not alter unrelated historical records.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl:
- Around line 476-616: Remove the duplicated AGENT_LEARNINGS record block from
the episodic ledger, including the repeated legacy daily-summary entry and its
associated replayed rows, while preserving the original block and all
intentional correction/lesson entries. Verify the remaining JSONL has no
duplicate lines and retains valid append-only ordering; do not alter unrelated
historical records.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 83421916-f8d7-4dca-ac37-445e6357d531
📒 Files selected for processing (4)
.agent/memory/episodic/AGENT_LEARNINGS.jsonl.agent/memory/episodic/snapshots/archive_2026-08-01.jsonl.agent/memory/working/2026-07-31-week-retrospective-pt-orama-collaboration-lessons.md.markdownlint-cli2.jsonc
🚧 Files skipped from review as they are similar to previous changes (1)
- .agent/memory/working/2026-07-31-week-retrospective-pt-orama-collaboration-lessons.md
…pisodic log
1. lessons.jsonl lines 965-966 (lesson_718c9430f44b, lesson_2d53056e593c):
conditions contained nearly every token from each claim, including a
tokenization fragment ('doesn'), rather than focused retrieval
triggers -- reduces selection precision if this field is used for
lesson retrieval. Replaced both with small, scenario-specific trigger
sets matching the established style (lesson_a8f3c2e91d04's 5-6-token
pattern), in both lessons.jsonl and the corresponding graduated
candidate JSON. This is a metadata correction (retrieval triggers),
not a claim rewrite -- the claim text itself is untouched.
2. AGENT_LEARNINGS.jsonl had 135 exact duplicate lines, including the
legacy daily-summary row appearing at both line 1 and line 476.
Verified precisely before fixing (135 confirmed, line-1-equals-
line-476 confirmed). Deduped by exact line match, keeping first
occurrence -- write-once episodic entries have no edit semantics, so
removing byte-identical replayed rows doesn't destroy any unique
information. 621 -> 486 lines, 0 duplicates remaining.
Both files valid JSON after the fix. Hygiene clean.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.agent/memory/episodic/AGENT_LEARNINGS.jsonl (1)
1-1: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winRoute this entry through
epoch_learnings.This row bypassed
.agent/tools/learn.pyand uses the legacydate/summaryshape instead of the canonicaltimestamp/action/evidence_idsmirror. Either add it through the learning tool in a stable episodic schema, or isolate legacy rows from replay.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl at line 1, Route this learning entry through the epoch_learnings path instead of storing it directly in the legacy episodic JSONL format. Use .agent/tools/learn.py to create the canonical timestamp/action/evidence_ids schema, or update replay to explicitly isolate and skip legacy date/summary rows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl:
- Line 49: Remove the real LAN endpoints from the source memory entry and any
other affected source records, then run the repository’s privacy-scrub and
re-render workflow so all derived views are updated consistently. Verify the
scrub covers the existing endpoint at the referenced earlier entry as well, and
append a neutral correction documenting the cleanup without reproducing
sensitive values.
---
Nitpick comments:
In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl:
- Line 1: Route this learning entry through the epoch_learnings path instead of
storing it directly in the legacy episodic JSONL format. Use
.agent/tools/learn.py to create the canonical timestamp/action/evidence_ids
schema, or update replay to explicitly isolate and skip legacy date/summary
rows.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a338940d-eefd-419f-a0b2-493f1c763efc
📒 Files selected for processing (4)
.agent/memory/candidates/graduated/2d53056e593c.json.agent/memory/candidates/graduated/718c9430f44b.json.agent/memory/episodic/AGENT_LEARNINGS.jsonl.agent/memory/semantic/lessons.jsonl
🚧 Files skipped from review as they are similar to previous changes (2)
- .agent/memory/semantic/lessons.jsonl
- .agent/memory/candidates/graduated/718c9430f44b.json
| {"timestamp": "2026-06-23T22:30:40+00:00", "skill": "ci-debugging", "action": "multi-ci-fix", "result": "success", "detail": "Fixed two CI failures in different repos. (A) orama-system run 27893218322: test_active_version_surfaces_are_09998 \u2014 pyproject.toml was already at 1.1.0.0 but test still asserted 0.9.9.9. Root cause: no single source of truth. Fix: src/orama_system/_version.py + scripts/sync_version.py propagating to 25+ surfaces; test rewritten to import EXPECTED dynamically, never hardcode. (B) Perpetua-Tools run 28015334534: AttributeError: module 'launch_researchers' has no attribute '_platform_for_role'. Root cause: commit d739aa2 described the fix in its message but never wrote the code. Fix: implemented _platform_for_role(), _pick_model_with_affinity(), added platform= param to _resolve_lmstudio_model/_resolve_ollama_model. PR #128 drafted \u2192 undrafted via GraphQL \u2192 squash-merged. 5/5 new tests pass.", "pain_score": 3, "importance": 9, "reflection": "Two recurring CI failure patterns: (1) Hardcoded version literals in tests drift from reality when the code is bumped. Prevention: tests must import version dynamically from the SSoT file. (2) Commit message describes a fix that was never implemented. The failing tests ARE the spec \u2014 read them first before guessing what to implement. For the PR #128 case: the test file was written by a different agent than the fix. The implementation agent wrote the commit message but not the code. Always verify: does the code actually exist, or just the commit message?", "confidence": 0.98, "source": {"skill": "ci-debugging", "profile": "claude-sonnet-4.6", "run_id": "2026-06-23-ci-fixes"}, "evidence_ids": ["orama-system:run/27893218322", "Perpetua-Tools:run/28015334534", "Perpetua-Tools:PR#128:0480ab05"]} | ||
| {"timestamp": "2026-06-23T22:30:40+00:00", "skill": "git-conflict-resolution", "action": "multi-file-conflict-resolution", "result": "success", "detail": "Applied combine-never-replace strategy across 11 git conflicts. Per-file decisions: (1) Additive content (empty ours + content theirs) \u2192 take theirs. (2) Append-style logs (LESSONS.md) \u2192 concatenate both sides. (3) Structural upgrade (06-multi-agent-collab.md SSoT table vs old 7-row) \u2192 take the superset after verifying all rows from the old version are present in the new. (4) Test files \u2192 build unified: take the more complete structure, integrate the defensive fallback (_ver() FileNotFoundError for pre-_version.py branches). (5) Architectural correctness (NEEDS_REVISION\u2192Plan vs NEEDS_REVISION\u2192Execute) \u2192 take architecturally correct side regardless of which branch it came from. (6) API correctness (lowercase vs mixed-case model IDs) \u2192 take lowercase.", "pain_score": 3, "importance": 9, "reflection": "The conflict resolution heuristic tree: Is one side empty and the other has content? \u2192 take the content side (additive). Are both sides partial and complementary? \u2192 concatenate or build unified. Is one a structural superset of the other? \u2192 verify inclusion, take the superset. Is one architecturally correct and the other has a bug? \u2192 take the correct one and document why. Never delete anything without explicit archival. The simulation step (merge --no-commit) is non-negotiable \u2014 without it you can't enumerate conflicts before touching anything.", "confidence": 0.98, "source": {"skill": "git-conflict-resolution", "profile": "claude-sonnet-4.6", "run_id": "2026-06-23-conflict-resolution"}, "evidence_ids": ["orama-system:PR#104:f388511", "orama-system:experiment/pt-orama-self-reflection:f388511"]} | ||
| {"timestamp": "2026-06-23T22:30:40+00:00", "skill": "git-multi-agent-coordination", "action": "nested-branch-merge", "result": "success", "detail": "Successfully orchestrated a three-agent nested-branch merge: PR #104 (codex/hermes-ecc-harness-skills, agent 1) based on PR #105 (experiment/pt-orama-self-reflection, agent 2), both diverged from main (agent 3 was also editing). Correct order: simulate ALL conflicts first \u2192 ask human about each \u2192 resolve 104\u2192105 (11 conflicts) \u2192 push \u2192 CI green \u2192 merge #104 \u2192 wait 10 min \u2192 simulate 105\u2192main (0 conflicts after resolution) \u2192 merge #105. Total: 11 conflicts resolved, 0 content lost, 14/14 CI green on both merges.", "pain_score": 4, "importance": 10, "reflection": "The key discipline: simulate ALL merges via 'git merge --no-commit --no-ff' BEFORE touching anything, enumerate every conflict, present them to the human with both sides shown, wait for decisions. Never guess conflict resolution. After human confirms strategy (combine-never-replace), resolve all 11 in one pass, test, push, then proceed to official API merge. The 10-minute buffer between merges matters \u2014 GitHub needs time to recompute mergeable_state after a merge. Checking mergeable_state=clean before merge 2 is the gate, not just the 10-min timer.", "confidence": 0.99, "source": {"skill": "git-multi-agent-coordination", "profile": "claude-sonnet-4.6", "run_id": "2026-06-23-pr104-pr105-merge"}, "evidence_ids": ["orama-system:PR#104:f388511", "orama-system:PR#105:2055c9b", "orama-system:main:2055c9b"]} | ||
| {"timestamp": "2026-06-23T22:30:40+00:00", "skill": "perpetua-core-knowledge", "action": "rc1-as-built-documentation", "result": "success", "detail": "Documented perpetua-core RC-1 salvage port completion in orama-system docs/v2/. All 16 tasks DONE (confirmed via PROGRESS.md at oramasys/perpetua-core HEAD 56f2a6d). 73 tests green across 3 repos (perpetua-core 56, oramasys 5, Perpetua-Tools 12). New modules: discovery/backend.py, probe.py, registry.py, selector.py, errors.py; message.py (OQ17 RESOLVED); plugins: tool_node, routing, validator, interrupt_guard, parallel; engine: set_entry(), compile(), max_steps guard (OQ12). docs/v2/15-phase1-as-built.md: new RC-1 section with full module table, engine changes, OQ resolutions, test breakdown, push gate. docs/v2/04-build-order.md: Phase 2 marked DONE. docs/v2/06-open-questions.md: OQ12, OQ17, OQ19 resolved. PUSH GATE STILL OPEN: Mac Ollama (localhost:11434) + Win LM Studio (192.168.254.103:1234) hardware review required before perpetua-core main merge.", "pain_score": 1, "importance": 9, "reflection": "The salvage translation design spec (2026-05-17) served as the ground truth. Comparing spec vs repo directly revealed that ALL 16 tasks were done same-day as the spec was written \u2014 the spec WAS the implementation plan and the implementation followed immediately. The push gate exists because the branch is local-only pending hardware review. Phase 3 (Orchestration & API Layer) is fully unblocked once the gate clears.", "confidence": 0.97, "source": {"skill": "perpetua-core-knowledge", "profile": "claude-sonnet-4.6", "run_id": "2026-06-21-perpetua-core-rc1"}, "evidence_ids": ["oramasys/perpetua-core:feat/salvage-plugins-rc1:56f2a6d", "orama-system:docs/v2/15-phase1-as-built.md:b700c2f", "orama-system:docs/v2/04-build-order.md:b700c2f"]} |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Scrub real LAN endpoints from tracked memory.
Lines 49 and 107 add 192.168.254.103:1234 and 192.168.254.100:1234. These values expose local fleet topology in a tracked append-only file. The file already contains another endpoint of the same class at Line 72.
Use the repository's privacy-scrub and re-render flow across source and derived views. Then append a neutral correction. Do not mask only a rendered copy.
Also applies to: 107-107
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agent/memory/episodic/AGENT_LEARNINGS.jsonl at line 49, Remove the real LAN
endpoints from the source memory entry and any other affected source records,
then run the repository’s privacy-scrub and re-render workflow so all derived
views are updated consistently. Verify the scrub covers the existing endpoint at
the referenced earlier entry as well, and append a neutral correction
documenting the cleanup without reproducing sensitive values.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.agent/memory/auto_dream.py (1)
38-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse one shared
is_legacy_episodic_rowimplementation.Both modules import the helper and then redefine the same symbol later. The later definitions shadow the imports.
.agent/memory/auto_dream.py#L38-L38: Remove the duplicate local definition at Lines 75-88 so this import resolves to.agent/harness/hooks/_episodic_io.py..agent/tools/show.py#L26-L30: Remove the duplicate local definition at Lines 75-88 so this import resolves to.agent/harness/hooks/_episodic_io.py.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.agent/memory/auto_dream.py at line 38, Remove the duplicate local is_legacy_episodic_row definitions so both modules use the imported shared helper from .agent/harness/hooks/_episodic_io.py: update .agent/memory/auto_dream.py at lines 75-88 and .agent/tools/show.py at lines 75-88; no direct change is needed at the import sites .agent/memory/auto_dream.py:38-38 or .agent/tools/show.py:26-30.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.agent/memory/auto_dream.py:
- Around line 66-71: The _load_entries_locked() flow filters legacy episodic
rows before run_dream_cycle() rewrites AGENT_LEARNINGS.jsonl, potentially
deleting them silently. Preserve filtered legacy rows independently during
replay, or explicitly document and test that this rewrite intentionally cleans
them up; ensure the chosen policy is implemented consistently around
is_legacy_episodic_row() and the kept-entry write path.
In @.agent/memory/episodic/snapshots/archive_2026-08-01.jsonl:
- Line 5: Update this episodic record to the canonical schema expected by
is_legacy_episodic_row, replacing the date/summary-only shape with timestamp and
action plus all required evidence fields. Preserve the existing event details in
the canonical fields, or remove the record if it is intended to remain
archival-only.
---
Nitpick comments:
In @.agent/memory/auto_dream.py:
- Line 38: Remove the duplicate local is_legacy_episodic_row definitions so both
modules use the imported shared helper from
.agent/harness/hooks/_episodic_io.py: update .agent/memory/auto_dream.py at
lines 75-88 and .agent/tools/show.py at lines 75-88; no direct change is needed
at the import sites .agent/memory/auto_dream.py:38-38 or
.agent/tools/show.py:26-30.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ec675819-1a2d-4282-9015-11d76994c17b
📒 Files selected for processing (5)
.agent/harness/hooks/_episodic_io.py.agent/memory/auto_dream.py.agent/memory/episodic/AGENT_LEARNINGS.jsonl.agent/memory/episodic/snapshots/archive_2026-08-01.jsonl.agent/tools/show.py
💤 Files with no reviewable changes (1)
- .agent/memory/episodic/AGENT_LEARNINGS.jsonl
| entry = json.loads(line) | ||
| except json.JSONDecodeError: | ||
| continue | ||
| if is_legacy_episodic_row(entry): | ||
| continue | ||
| entries.append(entry) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 6 \
'is_legacy_episodic_row|if not entries|_write_entries_locked' \
.agent/memory .agent/harness/hooksRepository: diazMelgarejo/Perpetua-Tools
Length of output: 6507
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== auto_dream.py relevant sections =="
sed -n '1,130p' .agent/memory/auto_dream.py
sed -n '185,215p' .agent/memory/auto_dream.py
echo
echo "== _episodic_io.py relevant sections =="
sed -n '70,120p' .agent/harness/hooks/_episodic_io.py
echo
echo "== decay_old_entries usages/usages with archived semantics =="
rg -n -C 4 'decay_old_entries|archived|snapshot|snapshot' .agent/memory .agent/harness/hooksRepository: diazMelgarejo/Perpetua-Tools
Length of output: 50385
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== target file sizes =="
wc -l .agent/memory/auto_dream.py .agent/harness/hooks/_episodic_io.py
echo
echo "== focused target slices =="
sed -n '50,215p' .agent/memory/auto_dream.py
printf '\n---\n'
sed -n '75,180p' .agent/harness/hooks/_episodic_io.py
echo
echo "== exact target identifiers =="
rg -n -C 3 '^def (is_legacy_episodic_row|_load_entries_locked|_write_entries_locked|decay_old_entries)|def (cluster_and_extract|write_candidates|write_review_queue_summary)|ARCHIVE|epoch|timestamp|date|summary|max_age|threshold|rfind|split\(|\.lstrip|with open|os\.replace|JSONDecodeError|FileNotFoundError' .agent/memory/auto_dream.py .agent/harness/hooks/_episodic_io.py
echo
echo "== related tests (if any) =="
rg -n -C 3 'auto_dream|legacy_episodic|AGENT_LEARNINGS|decay_old_entries' tests .pytest.ini pyproject.toml 2>/dev/null || trueRepository: diazMelgarejo/Perpetua-Tools
Length of output: 26421
Document or preserve filtered legacy episodes.
_load_entries_locked() skips date/summary rows when canonical rows exist, then run_dream_cycle() writes only kept back to AGENT_LEARNINGS.jsonl. This silently removes those legacy rows from the persistent store unless the file contains only legacy rows. If filtering is replay-only, archive them independently; otherwise add a test/docs note documenting the cleanup policy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.agent/memory/auto_dream.py around lines 66 - 71, The _load_entries_locked()
flow filters legacy episodic rows before run_dream_cycle() rewrites
AGENT_LEARNINGS.jsonl, potentially deleting them silently. Preserve filtered
legacy rows independently during replay, or explicitly document and test that
this rewrite intentionally cleans them up; ensure the chosen policy is
implemented consistently around is_legacy_episodic_row() and the kept-entry
write path.
…hema Convert date/summary archive entry to timestamp/action/evidence_ids so replay and dream clustering can process it without is_legacy_episodic_row skip.


9-part, evidence-grounded account of this week's actual incidents, not filtered for brevity: the orama<->PT sync policy documented then quietly violated; CVE-2025-30066 caught by verification discipline (and a third-party source's SHA found wrong by checking the real repo directly); CI workflow consolidation cascading into 3 more real bugs; the mv-into-existing-directory trap nearly dismissed as a bad test before being traced to ground; git am vs rebase state confusion; the append-only memory rule written then immediately violated by its own author, caught by external review; this session's own doctrine work getting the simple-vs-advanced hierarchy backwards, corrected by direct human instruction; and a consolidated list of recurring tooling/API gotchas that kept costing time even after individual capture.
Closes with Part 9: what this is actually about -- judgment developed in one session surviving into the next in a form an agent can act on, not a transcript a human has to re-explain every time. The repeated 'never assume, never guess, always ask' instruction restated as what it actually is: not a lack of trust in capability, but a response to the specific, real gap this document traces between an agent's confidence a task is complete and the task actually being complete.
2 new durable lessons extracted (the other incidents already had individual lessons captured earlier this week, checked before adding anything to avoid re-graduating the same claim twice):
966 lessons.jsonl lines, zero duplicate IDs. Both lessons' episodic mirrors confirmed. Hygiene clean. Retrospective doc: 0 markdownlint issues (fixed 5 duplicate-heading violations by making each part's sub-heading unique, not by suppressing the check).
Summary
Related issue, plan, or decision
Verification and evidence
python3 scripts/review/repo_hygiene.py .passespython3 -m pytest ...) — paste the summary lineRisk, compatibility, and rollout
Security review
SECURITY.mdwhere this change affects it.Checklist
.github/AUTHORIZED_CONTRIBUTORS.md; AI assistance isCo-authored-by, not author..agent/memory/change went through the memory tooling (not hand-edited JSONL), or the invariant was verified programmatically and noted below.Optional: knowledge capture
Optional: cross-repository or vendor-overlay impact
Optional: integration or conflict-resolution note
Additional context
Summary by CodeRabbit
Documentation
Knowledge Management
Bug Fixes
Tooling