Skip to content

fix: stop flagging dual-encoding pairs as contradictions (T60)#11

Merged
ipiton merged 1 commit into
mainfrom
feature/t60-steward-dual-encoding-fp
May 20, 2026
Merged

fix: stop flagging dual-encoding pairs as contradictions (T60)#11
ipiton merged 1 commit into
mainfrom
feature/t60-steward-dual-encoding-fp

Conversation

@ipiton

@ipiton ipiton commented May 20, 2026

Copy link
Copy Markdown
Owner

Что и зачем

steward_run(scope=full) на Sema (1879 memories) возвращал 64 contradictions — все false positives класса dual-encoding: одно событие хранится в двух слоях — raw session summary (Session close / X, lifecycle draft) и извлечённая/промоутнутая entity (Task complete: X, active/canonical). Они семантически почти идентичны by design, но conflict detection считал любую разницу lifecycle противоречием. На одном /memory-cleanup приходилось делать 69 ручных suppress, и это растёт линейно с числом закрытых задач.

Root cause

В hasContradictionSignals ветка if la != "" && lb != "" && la != lb { return true } срабатывала на естественной разнице draft vs canonical.

Fix

Разница lifecycle считается конфликтом только при явной инвалидации: одна сторона outdated/superseded, другая — живая (active/canonical/draft). Различия среди живых статусов (draftactivecanonical) — нормальное вызревание/dual-encoding, игнорируются. Настоящие same-layer противоречия по-прежнему ловятся через explicit supersession links, пересечение temporal-окон и content-keywords.

  • scanner.go: la != lblifecycleInvalidationConflict(la, lb)
  • tests: матрица lifecycle (симметрия), dual-encoding не флагается + same-layer invalidation/keyword флагается — unit (hasContradictionSignals) и полный scan-путь (scanSemanticConflicts)
  • docs: docs/STEWARDSHIP.md — секция dual-encoding policy

Acceptance (T60)

  • ✅ dual-encoding пары больше не флагаются → ожидаемо <5 contradictions вместо 64 на 1800+ corpus
  • ✅ fixture: same-layer disagreement флагается, dual-encoding — нет
  • ✅ docs обновлены

Проверка

  • go build ./... — OK
  • go test ./... — зелёные
  • новых lint-замечаний нет (2 pre-existing errcheck в audit.go/inbox.go не относятся к изменению)

Закрывает T60.

steward conflict detection treated any lifecycle difference between two
similar memories as a contradiction. The same event is routinely stored
at two layers — a raw session summary (lifecycle draft) and the
extracted/promoted entity (active/canonical) — which are near-identical
by design. This produced a large false-positive class: a full scan over
~1879 memories returned 64 contradictions, all dual-encoding pairs,
forcing dozens of manual suppress actions per cleanup.

A lifecycle difference now counts as a conflict only on explicit
invalidation: one side outdated/superseded while the other is live
(active/canonical/draft). draft<->active<->canonical differences are
normal maturation and ignored. Genuine same-layer disagreements are
still caught via explicit supersession links, temporal window overlap,
and content contradiction keywords.

- scanner.go: replace bare 'la != lb' signal with lifecycleInvalidationConflict
- tests: lifecycle matrix, dual-encoding skip + same-layer flag (unit + full scan path)
- docs: STEWARDSHIP.md dual-encoding policy section

Closes T60
@ipiton ipiton merged commit f73ec88 into main May 20, 2026
1 check passed
@ipiton ipiton deleted the feature/t60-steward-dual-encoding-fp branch May 20, 2026 08:41
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