Skip to content

Extract common hook protocol + experimental memory extraction#54

Merged
TensorTemplar merged 8 commits into
mainfrom
wip/minimax-m3-agent
Jun 29, 2026
Merged

Extract common hook protocol + experimental memory extraction#54
TensorTemplar merged 8 commits into
mainfrom
wip/minimax-m3-agent

Conversation

@TensorTemplar

Copy link
Copy Markdown
Owner

implements #50 and experimental memory extractor from project-related transcripts

Folds prior unsigned WIP commits into a single signed commit.

abstract hook protocol (issue #50):
Storage and analyzers operate on a single canonical AbstractHookEvent;
each harness owns its wire format via an adapter (ClaudeCodeAdapter,
OpenCodeAdapter). EventType values are snake_case canonical
(Migration015 translates legacy PascalCase).

multi-harness memory extraction (issue #46):
find_memories discovers and parses both Claude Code and OpenCode
sessions. OpenCode's message/<sid>/<message_id>.json +
part/<mid>/<part_id>.json tree is walked in chronological order and
emitted in the same USER:/ASSISTANT:/[TOOL: ...] format as the
Claude parser, so downstream LLM extraction is harness-agnostic.
processed_memory_sessions.source column (Migration017) prevents
cross-harness key collisions.

freshness validator (4-action LLM judge):
All open-ended judgment is deferred to the LLM. The dedupe threshold
is data-driven per project: p75 of the existing memory bank's
pairwise similarity distribution, clamped to [0.45, 0.95].
The judge picks one of keep_both / merge / supersede / dedupe.
supersede links existing to new via MemoryEntry.superseded_by
(Migration016) instead of flipping retained; merge rewrites the
candidate; dedupe skips save.

preflight:
find_memories validates both the chat LLM and embedding endpoint
via GET /v1/models before processing any session; aborts with
click.ClickException listing all failures. No partial batch
completion. --dry-run skips the check.

Truncation defaults (tool_input=120, tool_output=120,
tool_result=200) preserved as Pydantic-fielded defaults on
TranscriptTruncationConfig so callers can override without
hardcoding changes.

Verified: 976 tests pass; end-to-end on
/mnt/terradump/code/microagi/moelite with MicroAGI MiniMax-M3
endpoint from opencode.json (8 memories saved, freshness ran
KEEP_BOTH at sim=0.59, project p75=0.57 -> derived threshold 0.57).

Signed with 34A5902CFFFC0171037ABFE2F810974410C09E22
(Alex Korolev (HOT) <lxk@droidcraft.org>).
@TensorTemplar TensorTemplar changed the title Wip/minimax m3 agent Extract common hook protocol + experimental memory extraction Jun 24, 2026
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

📊 Slopometry QPE Report

QPE Score: 0.2476

Metric Value Description
MI (normalized) 0.289 Maintainability Index / 100
Smell Penalty 0.211 Weighted code smell deduction
Adjusted Quality 0.248 MI × (1 - smell_penalty) + bonuses
Code Smell Breakdown
Smell Count
inline import 252
orphan comment 210
dict get with default 92
swallowed exception 33
single method class 28
passthrough wrapper 17
hasattr getattr 15
untracked todo 8
test skip 6
type ignore 4
acknowledged silent except 1
nonempty init 1

Higher QPE = better quality

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

📈 Slopometry Impact Report

Impact: SIGNIFICANT IMPROVEMENT (score: 1.234)

Metric Delta Description
QPE +0.0359 Quality-Per-Effort change
MI +1387.641 Maintainability Index change
CC +1179.000 Cyclomatic Complexity change
Effort +8694371.9 Halstead Effort change
Count
Changed files 71
Blind spots 7
Smell Advantage Breakdown
Smell Baseline Current Weighted Delta
dict get with default 73 92 +0.9500
swallowed exception 27 33 +0.9000
orphan comment 243 210 -0.3300
inline import 219 252 +0.3300
single method class 23 28 +0.2500
type ignore 2 4 +0.1600
test skip 5 6 +0.1000
hasattr getattr 14 15 +0.1000
acknowledged silent except 0 1 +0.0500
passthrough wrapper 15 17 +0.0400
nonempty init 0 1 +0.0300

Source: Previous commit (a0a6bf8 vs 1cebbb1)

…tion

User-facing # Installation no longer smuggles dev-only advice ('After
making code changes, reinstall to update the global tool') that
confused the flow for first-time installers.

Promoted ### Development Installation (git clone + uv sync + uv run
pytest) from a buried sub-section under # Configuration to its own
top-level # Development section. The dev reinstall command now lives
there next to the clone instructions.

Also wrapped the shell-source lines in a bash fence (the snippet
was rendering as raw markdown lines before the next heading).
@TensorTemplar TensorTemplar force-pushed the wip/minimax-m3-agent branch from 3421b57 to a828b8f Compare June 24, 2026 08:25
…edback

After ACTION REQUIRED lists the swallowed_exception / acknowledged_silent_except
files, append a concrete example showing the exact comment format
('\# slopometry: allow-silent - <short reason>') so a human reviewer can
copy-paste it to acknowledge the handler after review and stop it from
blocking next time.

The hint appears only when a swallow-related smell is blocking (so it
doesn't clutter feedback for unrelated smells), and is symmetric:
both the swallowed (initial review) and acknowledged (mass-suppression
review) branches point at the same comment format and the inverse
operation (remove the marker to revert).

Also expanded the SmellDefinition.guidance text and the SmellCounts
Field descriptions for swallowed_exception, acknowledged_silent_except,
and test_skip to document the marker comment format + how to revert,
so the schema/docs stay in sync with the runtime hint.

3 new tests (swallow_hint_shown_when_swallowed_blocking,
swallow_hint_shown_when_acknowledged_increased,
swallow_hint_absent_when_no_swallow_smell) verify the hint is emitted
exactly when expected.
…cleanup

- Add stdin_timeout_seconds to Settings; remove 5.0s magic number from dispatch.py
- Remove migrations 016-018: tables are new in this branch, _create_tables has final schema
- Add include_superseded param to get_memories (filters superseded_by IS NULL by default)
- Remove redundant mark_session_processed from save_memories (caller owns that)
- Make source param required on mark_session_processed/is_session_processed
- Add FreshnessAction StrEnum with .color property
- Add FreshnessVerdict + LLMMemoryCandidate pydantic models for structured LLM JSON parsing
- Create llm_text.py with strip_llm_wrappers() + parse_llm_json() shared helpers
- Convert MemoryFreshnessValidator class to validate_freshness() function
- Make freshness thresholds configurable via Settings (floor/ceiling)
- Remove api_key='dummy' defaults from MemoryExtractor/MemoryFreshnessValidator
- Extract platform path helpers to settings.py (get_claude_projects_dirs, get_opencode_storage_root)
- Simplify EmbeddingService: move openai import inside try block
- Use FreshnessAction enum comparisons instead of string literals in commands.py and tests
- Move inline imports to module top-level (Counter/defaultdict, parse_llm_json, settings)
- Add return type annotations to _capture_git_state/_capture_project in dispatch.py
- Rename all tests to test_<fn>__<behavior_when_context> convention
- Add tests: superseded filtering, save_memories not marking session, preflight unreachable endpoint
- ruff: 0 errors; pyright: 0 errors; pytest: 979 passed, 5 skipped, 3 pre-existing failures
…wledge silent exception

- Remove map_tool_name from ClaudeCodeAdapter and OpenCodeAdapter (dead code, never called)
- Remove orphan section comments (# Memory types, # Memory) from models/__init__.py
- Add allow-silent marker to emit_event_from_stdin dispatch except block
  (hook subprocess must not crash the harness session)
- Add retired_reason column (migration 016) separate from superseded_by
- audit_staleness(): LLM checks existing memories against transcript for
  retirement (fixed bugs, completed work, outdated state)
- prune-memories CLI command for on-demand staleness sweeps
- Fix DEDUPE: skip saving deduped candidates instead of metadata tagging
- Fix MERGE: mark old memory superseded_by new merged entry
- Fix staleness audit: exclude freshly-saved memories from audit scope
- Action priority resolution: SUPERSEDE > MERGE > DEDUPE > KEEP_BOTH
  (only winning action's side effects apply per candidate group)
- Extract _call_llm_json helper to DRY reconciliation + staleness LLM calls
- Promote magic numbers to settings (memory_query_limit, transcript
  truncation, prune transcript window, reconciliation/staleness max_tokens)
- Hoist openai import to top-level in memory_freshness
- README: mark LLM-dependent features, add offline_mode config section,
  document concurrent sessions limitation
- CLAUDE.md: update core components, CLI commands, model paths
- Tests: 114 new tests across freshness, service, models, migrations,
  reconciliation priority, prune-memories CLI integration
@TensorTemplar TensorTemplar merged commit 1b516ec into main Jun 29, 2026
2 checks passed
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