Commit Graph

16 Commits

Author SHA1 Message Date
ClaudioDrews 58027b95e6 feat: add wiki watcher cron to setup.sh (hourly ingestion)
- setup.sh Phase 7b: install cron job for wiki_continuous_ingest.py
- watcher script: fallback to Docker .env for REDIS_PASSWORD in cron context
- Cron runs every hour with idempotent marker check
2026-06-07 13:23:20 -03:00
ClaudioDrews 57912f52d1 fix: normalize vault path case and permissions, remove DS-specific key references
- Fix Vault→vault fallback in wiki_continuous_ingest.py, bulk_wiki_ingest.py,
  backfill_decay_metadata.py (bug #1: path mismatch with setup.sh)
- Add chmod 755 on wiki/ and fabric/ after mkdir in Phase 6 (bug #2:
  600 permissions prevent Docker worker read access)
- Simplify API key detection: use OPENROUTER_API_KEY only, remove
  DS-specific fallback in key detection and .env writing
- Keep hooks.py fallback (tries generic first, then DS-specific) —
  correct for backward compatibility
2026-06-07 12:59:04 -03:00
Claudio Drews 251c16ffad feat: collapse v2 — attenuate Hebbian boost by query-local salience (#24)
- score_all() now multiplies amplify_gain by base salience before
  applying Hebbian cross-source corroboration boost, so globally-
  important structural facts no longer crowd out query-locally-
  relevant facts
- ICARUS_COLLAPSE_AMPLIFY_GAIN env var (default 0.15) tunes the
  tradeoff; raise to 0.20 if genuine corroboration feels undervalued
- All tests passing (_test_collapse.py, collapse_eval.py)
- Real pipeline test: 30-35% token reduction with correct ranking

Closes #23

Co-authored-by: ClaudioDrews <claudio@drews.com.br>
2026-06-07 09:48:00 -03:00
ClaudioDrews d696168b89 feat: add verify_soul_config.py — check SOUL.md for Memory OS additions (fixes #19)
Detects whether the four required Memory OS SOUL.md sections are present:
- Ground Truth Hierarchy (layer 7)
- Context Injection Convention
- Fact Feedback Rule
- Honcho Deprecation Notice

Case-insensitive keyword matching. Exits 0 if all pass, 1 otherwise.
Without these sections, injected memory is treated as external sources
to cite rather than prior knowledge — causing the 'internal mechanics leak'
behavior reported in #19.
2026-06-07 08:25:52 -03:00
ClaudioDrews 6418ed30a1 v0.2.0 — automated install, community infra, 20+ audit fixes
- setup.sh: one-command install (curl | bash), 10 phases, idempotent
- smoke_test.sh + test_ingestion.py: post-install verification
- .github/: issue templates, PR template, contributing guide
- QUICKSTART.md: quick start with setup.sh as primary method
- README: release notes, install links
- install.md: banner redirecting to automated install
- All docs translated to English
2026-06-05 01:51:24 -03:00
ClaudioDrews 35f85066a4 fix: semantic_dedup.py — adicionar using='dense' ao QueryRequest
Collection knowledge_base usa named vectors (dense + sparse). O Qdrant
exige o parâmetro 'using' em collections com múltiplos vetores nomeados.
Sem ele, query_batch_points retornava 'Not existing vector name error'
em 100% das batches (44/44). O script reportava falsos 0 near-duplicates.

Correção: 1 linha — using='dense' em models.QueryRequest (linha 176).

Validado com --dry-run --threshold 0.95 contra 8886 pontos reais:
0 erros, 1776 near-duplicate pairs detectados.
2026-06-03 15:59:28 -03:00
ClaudioDrews 144795bf74 perf: Qdrant query_batch_points + SQLite FTS5 for semantic_dedup and fabric-retrieve
V4.01: Replace O(n²) brute-force cosine similarity in semantic_dedup.py
  with Qdrant query_batch_points() — delegates nearest-neighbor search
  to the native HNSW index. Batch size auto-scales (min 200, adjusted
  for collection size). Self-match excluded server-side via
  HasIdCondition filter. Graceful fallback if qdrant-client not installed.

V4.03: Replace glob+parse in fabric-retrieve.py retrieve() with SQLite
  fabric_index + fabric_fts (FTS5). _ensure_fabric_index() rebuilds the
  index lazily when any fabric .md mtime exceeds the stored max mtime.
  Transactional rebuild (BEGIN; DELETE; DELETE; ...; COMMIT) prevents
  index corruption on partial failure. All score_entry fields preserved
  as columns — no YAML parsing after initial index build.
2026-06-03 12:14:30 -03:00
ClaudioDrews 1422a6d583 fix: resolve 5 easy Phase 4 performance/resilience issues
V4.04: Add retry_transient() to dlq_manager — re-enables reported transient
  failures for retry with --retry CLI flag, increments retry_count/last_retry

V4.05: save_report() now truncates JSONL to MAX_REPORT_HISTORY entries
  after each append (best-effort rotation)

V4.06: Wrap datetime.fromisoformat() in try/except (ValueError, TypeError)
  in get_status_summary() — skips entries with malformed timestamps

V4.08: Replace body[:50] dedup key with hashlib.sha256(body).hexdigest()
  in fabric-retrieve.py deduplicate()

V4.09: Add OrderedDict LRU cache (256 entries) to embedding.py get_embedding()
  — avoids recomputing embeddings for repeated text
2026-06-03 11:53:18 -03:00
ClaudioDrews e5edb58a19 fix: resolve all 8 Phase 3 config/path issues
V3.01-V3.03: Replace hardcoded Path.home() / 'Vault' with os.environ.get()
  - wiki_continuous_ingest.py: WIKI_ROOT via env with fallback
  - bulk_wiki_ingest.py: WIKI_ROOT + EMBEDDING_MODEL via env with fallback
  - backfill_decay_metadata.py: VAULT_ROOT via VAULT_PATH env with fallback

V3.04-V3.05: Replace hardcoded EMBEDDING_MODEL string with os.environ.get()
  - context_enhancer.py + bulk_wiki_ingest.py

V3.06: Replace ~/.hermes til fallback with ./hermes (Docker doesn't expand ~)

V3.07: Add /fabric volume mount (~/Vault/fabric:/fabric:rw)

V3.08: Add Qdrant healthcheck + change worker qdrant dependency from
  service_started to service_healthy
2026-06-03 11:44:22 -03:00
ClaudioDrews 55ba9cee1c fix: move get_sparse_vector outside get_embedding body (V2.12 regression)
get_sparse_vector was accidentally inserted between get_embedding's
signature and its body, disconnecting the embedding call and leaving
module-level code referencing undefined variables. Moved to standalone
function before get_embedding.
2026-06-03 11:03:18 -03:00
ClaudioDrews a3d644a5c9 fix: resolve 4 code-critical issues from Fase 2 audit
V2.07 (A01): Replace subprocess.run(['arq', ...]) with programmatic
  arq.worker.run_worker(WorkerSettings). Fixes signal handling,
  graceful shutdown, and logging unification.

V2.10 (D11): Fix filename → file_path in backfill_decay_metadata.py
  resolve_timestamp() now reads payload.file_path (consistent with
  what bulk_wiki_ingest.py writes). Replaced VAULT_ROOT path
  reconstruction with direct Path(file_path).

V2.11 (D05): Auto-create Qdrant collection in bulk_wiki_ingest.py
  If collection doesn't exist, creates it with hybrid schema
  (dense 4096d Cosine + sparse BM25) instead of sys.exit(1).

V2.12 (D27): Add sparse vector generation to bulk_wiki_ingest.py
  Optional fastembed BM25 sparse vectors alongside dense embeddings.
  Falls back to dense-only if fastembed not installed. Vectors stored
  as Qdrant named vectors: {'dense': ..., 'sparse': ...}
2026-06-03 10:54:53 -03:00
ClaudioDrews 4e1f543a1d docs: rewrite installation guide with real scripts and idempotent modifications (fixes #11)
Replace incomplete/outdated install instructions with accurate,
detailed steps grounded in production infrastructure.

setup/install.md:
- Step 3: run docker compose in-place (not via cp to ~/memory-os/)
- Step 5: explicit ~/.hermes/rulebook.md path, create-if-missing,
  idempotency guard with Memory OS Additions v1 marker
- Step 6: document VAULT_PATH, wiki directory structure,
  link to vault-curator as optional enrichment tool
- Step 7: replace fictional crontab with real maintenance scripts
  and hermes cron create commands; add backfill prerequisite note
  and exempt-prefix env var docs

setup/rulebook.md (NEW):
- Generic template with 3 blocks: Memory Architecture,
  Memory OS infrastructure, Mandatory Verifications
- Idempotency markers on every block

modifications/soul-rulebook.md:
- SOUL.md-only (rulebook sections moved to setup/rulebook.md)
- Conditional instructions (add level 2 vs full hierarchy)
- Conflict resolution table (4 rules)
- Context injection convention with acting vs reasoning distinction

scripts/:
- 8 maintenance scripts updated with sanitized equivalents
- decay_scanner.py, semantic_dedup.py: collection_ → DECAY/DEDUP_EXEMPT_PREFIXES env vars
- reflection_trigger.py: hardcoded venv path → /usr/bin/env python3
- All shebangs normalized, all internal references removed
2026-06-03 09:29:19 -03:00
ClaudioDrews 598eaf19d0 fix(sanitize): change system prefix replacement from silent removal to [REDACTED]
- Silent removal (empty string) left grammatically broken sentences
  and no audit trail. [REDACTED] preserves context structure.
- Control chars and zero-width Unicode keep empty string replacement
  (invisible characters, removal is correct).
- Updated 4 test assertions in _test_sanitize.py.
2026-06-02 13:45:02 -03:00
David Soff a5c1344afb
security(hooks, context_enhancer): add dual-layer prompt injection sanitization (#5)
security(hooks, context_enhancer): add dual-layer prompt injection sanitization

- Layer 1 (hooks.py): aggressive sanitization at prompt boundary with
  11 regex patterns + heuristic. Detects override directives, template
  injection, URI schemes, system prefixes, HTML/XML, control chars,
  zero-width Unicode, and code fences. Applied to fabric, Qdrant,
  sessions, and facts injection points. Complements existing
  _is_system_injection() (which filters ingest, not egest).

- Layer 2 (context_enhancer.py): lightweight sanitization on all
  search result content_preview outputs (hybrid, dense, sparse,
  lexical, sqlite).

- _test_sanitize.py: manual validation script with 24 test cases.

- Replacement strategy: [REDACTED] preserves audit trail and
  grammatical context instead of silent removal.
2026-06-02 13:43:34 -03:00
David Soff 0d6fc33c00
fix(context_enhancer): refactor embed_query_sparse to use stdin (#4)
fix(context_enhancer): refactor embed_query_sparse to use stdin instead of f-string interpolation

- Eliminates shlex.quote() crash with apostrophes (SyntaxError in subprocess)
- Eliminates user text interpolation into Python code string
- Hardcodes BM25 model name (was already hardcoded module-level)
- Corrects FastEmbed API usage: model.embed([query]) instead of model.embed(string)
2026-06-02 13:28:32 -03:00
ClaudioDrews 0b32ffcfc2 Initial commit: Memory OS — 6-layer memory architecture for Hermes Agent 2026-05-31 16:50:37 -03:00