Kwame approved wiring duplicate detection into the Memory Fixer. This is the institutional half of that change (the executable half already landed in the okyeame-memory-fixer cron prompt).
What this adds
Level 1 phase 5 — Duplicate-Node Detection. Read-only: runs memory_dup_detect.py --json (the clustering logic lives in that script, not in the prompt) and reports clusters by the verdict field:
verdict
meaning
required action
WRITER-DEFECT (run_family)
one scheduled task creating a node per run
writer fix, never merge (per-run nodes are the audit trail)
SAFE-MERGE
bodies identical
still needs an explicit Kwame merge #A into #B
HUMAN-DECISION
same subject, bodies differ
propose connect (edge), never merge
Why the old rule had to go
Line 131 defined duplicates as "same title or >70% title overlap". A full-graph audit (402 nodes, 2026-09-26) shows that rule false-positives on genuinely distinct work:
#357/#358/#359/#361 — four different BAF client workflows (bodies 0.15–0.24 apart)
#1792/#1793 — two different machines' Infisical migrations (0.23)
#545/#546, #1794/#1796 — same subject, distinct content
Acting on that rule would have merged distinct content irrecoverably. The real defect it hid was a writer: agent-zero's weekly-fleet-docker-update created #1902 → #1918 → #1921, title similarity 1.0, span 7 days, zero edges on every member. That is a writer fix, not a merge.
Corrected in the same pass
Stale canonical pointer: the file claimed /root/.hermes/contracts/memory-fixer-v3.md was the executable truth. That path does not exist on kagentz (no /root access from this container) — verified unreachable, not merely stale. The job's instruction set is inline in ~/.hermes/cron/jobs.json (hermes cron edit --prompt, no --prompt-file), and ~/.hermes/cron/memory-fixer-prompt.md had silently diverged from the live prompt by ~800 chars.
Reporting model: "reports to Kwame via this Zulip DM" described the pre-2026-09-21 shape. Verified: the fixer had been POSTing Zulip messages behind the gate (msg 86328 at 19:15:47Z, with no gate release record). Reports now DROP to the gate (comms_drop.py); exit 0 means QUEUED, never delivered.
Checks: added a line so a skipped phase 5 is visible — a silently skipped detection phase is precisely the failure this phase exists to prevent.
Executable side: prompt edit applied to cron job 7f60b5a553a4 and read back byte-identical
Kwame approved wiring duplicate detection into the Memory Fixer. This is the institutional half of that change (the executable half already landed in the `okyeame-memory-fixer` cron prompt).
## What this adds
**Level 1 phase 5 — Duplicate-Node Detection.** Read-only: runs `memory_dup_detect.py --json` (the clustering logic lives in that script, not in the prompt) and reports clusters by the `verdict` field:
| verdict | meaning | required action |
|---|---|---|
| `WRITER-DEFECT` (`run_family`) | one scheduled task creating a node per run | writer fix, **never merge** (per-run nodes are the audit trail) |
| `SAFE-MERGE` | bodies identical | still needs an explicit Kwame `merge #A into #B` |
| `HUMAN-DECISION` | same subject, bodies differ | propose **connect (edge)**, never merge |
## Why the old rule had to go
Line 131 defined duplicates as "same title or >70% title overlap". A full-graph audit (402 nodes, 2026-09-26) shows that rule false-positives on genuinely distinct work:
- `#357/#358/#359/#361` — four *different* BAF client workflows (bodies 0.15–0.24 apart)
- `#1792/#1793` — two *different machines'* Infisical migrations (0.23)
- `#545/#546`, `#1794/#1796` — same subject, distinct content
Acting on that rule would have merged distinct content irrecoverably. The real defect it hid was a writer: agent-zero's `weekly-fleet-docker-update` created `#1902 → #1918 → #1921`, title similarity **1.0**, span 7 days, **zero edges on every member**. That is a writer fix, not a merge.
## Corrected in the same pass
- **Stale canonical pointer:** the file claimed `/root/.hermes/contracts/memory-fixer-v3.md` was the executable truth. That path does not exist on kagentz (no `/root` access from this container) — verified unreachable, not merely stale. The job's instruction set is **inline in `~/.hermes/cron/jobs.json`** (`hermes cron edit --prompt`, no `--prompt-file`), and `~/.hermes/cron/memory-fixer-prompt.md` had silently diverged from the live prompt by ~800 chars.
- **Reporting model:** "reports to Kwame via this Zulip DM" described the pre-2026-09-21 shape. Verified: the fixer had been POSTing Zulip messages *behind* the gate (msg 86328 at 19:15:47Z, with no gate release record). Reports now DROP to the gate (`comms_drop.py`); exit 0 means QUEUED, never delivered.
- **Checks:** added a line so a skipped phase 5 is visible — a silently skipped detection phase is precisely the failure this phase exists to prevent.
Version 2.1.0 → 2.2.0 (new Level 1 phase).
## Verification
- `bash scripts/prose-lint.sh` → **LINT PASSED**, secret scan clean (run locally pre-push)
- Detector verified live: `ids=[1902,1918,1921] sim=1.0 unlinked=True verdict=WRITER-DEFECT span=7d agents=['agent-zero','agent-zero','agent-zero']`
- Executable side: prompt edit applied to cron job `7f60b5a553a4` and read back byte-identical
Level 1 gains phase 5, duplicate-node detection: runs
memory_dup_detect.py (read-only) and reports clusters by verdict.
- WRITER-DEFECT (run_family): one task creating a node per run -> writer
fix, never merge (per-run nodes are the audit trail)
- SAFE-MERGE: identical bodies, still needs an explicit Kwame decision
- HUMAN-DECISION: same subject, bodies differ -> connect, never merge
Replaces the naive '>70% title overlap' duplicate rule, which false-positives
on distinct work: four client workflows (#357-#361) and two machines'
migrations (#1792/#1793) score high on titles with bodies 0.1-0.3 apart.
Also corrected in the same pass:
- the 'canonical copy' pointer named /root/.hermes/contracts/memory-fixer-v3.md,
which does not exist on kagentz (no /root access); the job's instruction set is
inline in ~/.hermes/cron/jobs.json
- 'reports to Kwame via this Zulip DM' described the pre-2026-09-21 model; the
report is DROPped to the gate (comms_drop.py) and exit 0 means QUEUED, not sent
- added a Checks line so a skipped phase 5 is visible in the report
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Kwame approved wiring duplicate detection into the Memory Fixer. This is the institutional half of that change (the executable half already landed in the
okyeame-memory-fixercron prompt).What this adds
Level 1 phase 5 — Duplicate-Node Detection. Read-only: runs
memory_dup_detect.py --json(the clustering logic lives in that script, not in the prompt) and reports clusters by theverdictfield:WRITER-DEFECT(run_family)SAFE-MERGEmerge #A into #BHUMAN-DECISIONWhy the old rule had to go
Line 131 defined duplicates as "same title or >70% title overlap". A full-graph audit (402 nodes, 2026-09-26) shows that rule false-positives on genuinely distinct work:
#357/#358/#359/#361— four different BAF client workflows (bodies 0.15–0.24 apart)#1792/#1793— two different machines' Infisical migrations (0.23)#545/#546,#1794/#1796— same subject, distinct contentActing on that rule would have merged distinct content irrecoverably. The real defect it hid was a writer: agent-zero's
weekly-fleet-docker-updatecreated#1902 → #1918 → #1921, title similarity 1.0, span 7 days, zero edges on every member. That is a writer fix, not a merge.Corrected in the same pass
/root/.hermes/contracts/memory-fixer-v3.mdwas the executable truth. That path does not exist on kagentz (no/rootaccess from this container) — verified unreachable, not merely stale. The job's instruction set is inline in~/.hermes/cron/jobs.json(hermes cron edit --prompt, no--prompt-file), and~/.hermes/cron/memory-fixer-prompt.mdhad silently diverged from the live prompt by ~800 chars.comms_drop.py); exit 0 means QUEUED, never delivered.Version 2.1.0 → 2.2.0 (new Level 1 phase).
Verification
bash scripts/prose-lint.sh→ LINT PASSED, secret scan clean (run locally pre-push)ids=[1902,1918,1921] sim=1.0 unlinked=True verdict=WRITER-DEFECT span=7d agents=['agent-zero','agent-zero','agent-zero']7f60b5a553a4and read back byte-identical