Skip to content

feat(jme): Phase 3 — temporal filter + vector ceiling + jme-stats - #30

Merged
kosm1x merged 2 commits into
mainfrom
jarvis/feat/jme-phase3
Jul 17, 2026
Merged

feat(jme): Phase 3 — temporal filter + vector ceiling + jme-stats#30
kosm1x merged 2 commits into
mainfrom
jarvis/feat/jme-phase3

Conversation

@kosm1x

@kosm1x kosm1x commented Jul 17, 2026

Copy link
Copy Markdown
Owner

JME Phase 3 — PR #30

Three independent monitoring/quality improvements. No schema changes, no wiring changes, no new infra.

Pieza 1 — Temporal filter in queryMemory()

New deduplicateFacts() groups recall candidates by cosine similarity (TEMPORAL_DEDUP_THRESHOLD=0.85) and keeps only the most-recent fact per cluster. Prevents contradictory v1/v3 facts from appearing in the same context window.

Pieza 2 — Vector ceiling surveillance

consolidateAll() now counts embedded facts at each nightly run. Warns at >=400 (VECTOR_CEILING_WARN). LIMIT 500 in queryMemory() starts degrading at ~400 rows.

Pieza 3 — mc-ctl jme-stats dashboard

New cmd_jme_stats() command showing: fact store counts, vector ceiling status, recall utility (was_used breakdown), daily breakdown (7d), baseline comparison, and verdict runway to 2026-07-27.

Tests

6 new cases for deduplicateFacts(). All 33 tests pass. tsc: zero errors.

PiotrCoderDroid and others added 2 commits July 17, 2026 10:41
…hboard

Pieza 1 — Temporal dedup in queryMemory():
- New deduplicateFacts() groups recall candidates by cosine similarity
  (threshold=0.85) and keeps only the most-recent fact per cluster.
- Prevents contradictory v1/v3 versions of the same fact from landing
  in the same context window.
- factEmbeddings map collected during vector search, passed to dedup.
- Only activates when vector embeddings are present (FTS5-only path
  passes through unchanged).

Pieza 2 — Vector ceiling surveillance in consolidateAll():
- Counts jme_facts with embeddings at each nightly run.
- Emits console.warn when count >= VECTOR_CEILING_WARN (400).
- LIMIT 500 in queryMemory() starts degrading at ~400 rows.
- No pruning yet (Phase 4); this gives visibility before it becomes
  a bottleneck.

Pieza 3 — mc-ctl jme-stats command:
- New cmd_jme_stats() function in mc-ctl.
- Shows: fact store counts, vector ceiling status, turn buffer depth,
  recall utility (was_used breakdown), daily breakdown (last 7d),
  baseline comparison across all sources, and verdict runway to 2026-07-27.
- Registered in dispatch (jme-stats) and usage() help text.

Tests: 6 new cases for deduplicateFacts() in jme.test.ts.
All 33 tests pass. tsc --noEmit: zero errors.
…e newest

The anchor loop broke out on the FIRST newer candidate, leaving the rest
of the cluster un-absorbed — a v1/v2/v3 trio of the same fact surfaced
both v2 AND v3 (repro: identical embeddings, ts 100/200/300 → [v2, v3]),
defeating the feature's whole purpose ("solo v3 llega al contexto").
Now each anchor absorbs every ≥threshold member first and keeps the
single max-ts survivor at the anchor's rank position. 3-member regression
test added — 2-member cases cannot express this failure.

Relands the fix from task 595947aa, which ran in the nanoclaw sandbox and
never reached the host.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186BhSFY9sFFHCPeFnpbvki
@kosm1x

kosm1x commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

Operator-session review + fix relanded (a81e160):

Blocking bug (now fixed): deduplicateFacts broke out of the cluster scan on the first newer candidate, so a 3+ member cluster leaked multiple versions — repro with identical embeddings, ts 100/200/300 returned [v2, v3] instead of [v3]. Jarvis's own fix (task 595947aa) was correct in approach but ran in the nanoclaw sandbox and never landed on this branch. Relanded: absorb the full cluster per anchor, keep the max-ts survivor; 3-member regression test added (2-member tests cannot express this failure). Full suite green (6978).

Non-blocking notes for a future pass: the new function's docstring still references a queryVec param that doesn't exist, and dedup runs after .slice(0, k) so removals shrink results below k (acceptable, but deliberate-comment-worthy).

🤖 Generated with Claude Code

@kosm1x
kosm1x merged commit a9fc14b into main Jul 17, 2026
4 checks passed
kosm1x pushed a commit that referenced this pull request Jul 17, 2026
…losure record

Records the three arcs (consolidator fix proven in prod, gh_create_pr
cwd/upstream root cause + gate PASS 66.87, PR #30 forensics incl. the
nanoclaw sandbox-evaporation finding) and queues the systemic follow-ups
(nanoclaw work-landing check, coding-playbook repo map).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186BhSFY9sFFHCPeFnpbvki
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.

2 participants