diff --git a/.gitignore b/.gitignore index eb718f6..6239890 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ Thumbs.db # tech-debt-scan artefacts .tech-debt/ +# tech-debt-scan: track the baseline, ignore the rest of the workdir +!.tech-debt/ +.tech-debt/* +!.tech-debt/baseline.json diff --git a/.tech-debt/baseline.json b/.tech-debt/baseline.json new file mode 100644 index 0000000..32dcf53 --- /dev/null +++ b/.tech-debt/baseline.json @@ -0,0 +1,1432 @@ +{ + "schema_version": 2, + "last_scan": "2026-09-09", + "preset": "balanced", + "findings": { + "0057072f12baa1da": { + "family": "complex-units", + "file": "better_memory/services/reflection.py", + "line_start": 1444, + "quote_hash": "424f1b61d5afc6a920cb7ca042aa4bb3725e38a5", + "quote": " buckets[polarity] = [self._bucket_item(r) for r in group[:cap]]\n continue\n tested_idx = [i for i, r in enumerate(group)\n if _wilson_rated(r) >= EXPLORATION_RATED_FLOOR]\n untested_idx = [i for i, r in enumerate(group)\n if _wilson_rated(r) < EXPLORATION_RATED_FLOOR]", + "title": "retrieve_reflections mixes SQL build, ranking, fusion, fill and exposure writes", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-retrieve-reflections-mixes-sql-build-ranking-fusion-fill-and-exp-2026-09-09" + }, + "035bf301e82fbc6a": { + "family": "complex-units", + "file": "better_memory/storage/agentcore.py", + "line_start": 869, + "quote_hash": "9dbcc53839daeec24da66409e01184ea92118920", + "quote": " if isinstance(body, dict) and not body.get(\"title\") and (\n body.get(\"situation\") or body.get(\"reflection\")\n ):\n aws_title, aws_use_cases, aws_hints = _derive_aws_reflection_fields(body)", + "title": "_parse_reflection_record decodes 15+ fields with per-field fallback chains", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "03a9d09600efbd9c": { + "family": "dependency-debt", + "file": "pyproject.toml", + "line_start": 14, + "quote_hash": "6437c4c18d290e47d1855fef32dbed1d377243ed", + "quote": " \"sqlite-vec>=0.1\",\n \"httpx>=0.27\",\n \"pydantic>=2\",\n \"flask>=3\",\n \"markupsafe>=2\",\n]", + "title": "Runtime and dev dependencies declared with lower bounds only or no bound at all", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "0540700e1977942c": { + "family": "duplication", + "file": "better_memory/ui/queries.py", + "line_start": 574, + "quote_hash": "1d52905b09b601c77c45f4560ceea78137dffa7c", + "quote": " \"SELECT DISTINCT project FROM observations \"\n \"WHERE project IS NOT NULL AND project != '' \"\n \"ORDER BY project COLLATE NOCASE\"", + "title": "distinct-projects dropdown query written three times, differing only in table", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "06c5a34c275e03d3": { + "family": "architecture", + "file": "better_memory/mcp/server.py", + "line_start": 195, + "quote_hash": "beea030e64e15101f992f5863b1e4ded72d29ac8", + "quote": " remote: StorageBackend | None = (\n backend if config.storage_backend == \"agentcore\" else None\n )", + "title": "Every MCP data tool has two implementations gated on `remote is not None`", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "075068dc69956ae9": { + "family": "error-masking", + "file": "tests/search/test_hybrid.py", + "line_start": 16, + "quote_hash": "ee47cc15f90140668752e25bb0e35fddb4515a4f", + "quote": "_LEGACY_SKIP = pytest.mark.skip(\n reason=\"Awaiting Phase 2 episodic service layer \u2014 see docs/superpowers/specs/2026-04-20-episodic-memory-design.md\"\n)", + "title": "14 of 16 hybrid-search tests unconditionally skipped while hybrid_search is on t", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "091d71ddc8600b3f": { + "family": "half-finished", + "file": "better_memory/services/memory_rating.py", + "line_start": 183, + "quote_hash": "5f76c8f14aa93847c29d8608742021b781d5f636", + "quote": " required. `evidence` defaults to None only as a runtime-safety\n compat shim for callers that have not yet been updated to pass\n it (see MCP `memory.credit` handler) \u2014 None fails validation\n with a clear ValueError instead of a TypeError, so an un-updated\n caller gets a clean error response rather than a crash.", + "title": "memory_rating evidence=None compat shim cites a caller that now always sends evi", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "09c012ba7a060fdd": { + "family": "dead-code", + "file": "better_memory/storage/session.py", + "line_start": 63, + "quote_hash": "bd6119f5e979bcd41dc64a48f1b78520f28c0ff3", + "quote": "def closure_event_payload() -> list[dict]:\n \"\"\"Canonical closure-marker payload for the Stop hook's final CreateEvent.", + "title": "storage/session.closure_event_payload is never called", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "0ebecd87384ba7f6": { + "family": "error-masking", + "file": "better_memory/storage/agentcore.py", + "line_start": 2234, + "quote_hash": "23729e4c064de5b50ba21bbf2543097e81baea33", + "quote": " self._local_conn.commit()\n except Exception: # noqa: BLE001 - local stamp must never block credit_one\n pass", + "title": "credit_one swallows local stamp failure after the AWS counter was already bumped", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "116b48eac86ef959": { + "family": "architecture", + "file": "better_memory/services/relevant.py", + "line_start": 123, + "quote_hash": "039bcfa43daa7cd581028b9faedda568c370f4f1", + "quote": "def retrieve_relevant(\n backend: Any,", + "title": "Service layer identifies the backend by duck-typing because it types it as Any", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "117d498d9bf1806b": { + "family": "god-classes", + "file": "better_memory/services/reflection.py", + "line_start": 321, + "quote_hash": "cf9070d3826d4fd69903dcd62695bf885fd8a68e", + "quote": "class ReflectionSynthesisService:\n \"\"\"Orchestrates pre-start synthesis: load, prompt, parse, apply, return.", + "title": "ReflectionSynthesisService mixes synthesis, prompt authoring and retrieval", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "17764229b32f26b0": { + "family": "god-classes", + "file": "better_memory/ui/app.py", + "line_start": 40, + "quote_hash": "2b514d725eedc5e41a374bc8d4c69760b44dbdbe", + "quote": "def create_app(\n *,\n inactivity_timeout: float = 1800.0,\n inactivity_poll_interval: float = 30.0,\n start_watchdog: bool = True,\n db_path: Path | None = None,", + "title": "create_app packs 5 route domains, security policy, watchdog and raw SQL", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "19c734e9f96f63c0": { + "family": "complex-units", + "file": "better_memory/storage/agentcore.py", + "line_start": 2465, + "quote_hash": "b53728ec8303ac8d69c9c5e6832dadebef977ea8", + "quote": " self._local_conn.rollback()\n except Exception: # noqa: BLE001 - rollback failures are terminal for this loop iteration only\n pass\n continue\n\n try:", + "title": "apply_session_ratings nests try/except three deep inside its rating loop", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "1ab8340b39169cc0": { + "family": "security", + "file": "better_memory/setup/engine.py", + "line_start": 601, + "quote_hash": "64c9c58030de869f612a42dfe9638c3d9cf22936", + "quote": " result = subprocess.run(\n [\"cmd\", \"/c\", \"mklink\", \"/J\", str(link), str(source)],\n capture_output=True, timeout=10,\n )", + "title": "Windows symlink fallback shells out through cmd /c with interpolated paths", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "1b65de9019cb5b39": { + "family": "error-masking", + "file": "better_memory/storage/agentcore.py", + "line_start": 1063, + "quote_hash": "d29fed1ed299c06f4eac0e9dca2708d308733163", + "quote": " for namespace in namespaces:\n try:\n summaries = self._list_records_paginated(namespace, max_results=limit * 2)\n except Exception: # noqa: BLE001 - best-effort; one namespace failing must not 500\n continue", + "title": "Reflection listing returns partial results when a namespace fetch fails, with no", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-reflection-listing-returns-partial-results-when-a-namespace-fetc-2026-09-09" + }, + "1ce774f266b2d44e": { + "family": "security", + "file": ".github/workflows/bugbot.yml", + "line_start": 25, + "quote_hash": "1fc0bbbe2db1cb6a8d04c13cbe847d575b38c3db", + "quote": " uses: rekpero/claude-bugbot-github-action@main\n with:\n claude-setup-token: ${{ secrets.CLAUDE_SETUP_TOKEN }}", + "title": "CI passes a repo secret to a third-party action pinned to a mutable @main ref", + "tier": "B", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "21339e468ddc269c": { + "family": "architecture", + "file": "better_memory/storage/agentcore.py", + "line_start": 207, + "quote_hash": "c73594ad4b5b6fc9ef51ae3bdae244b0f1d5391c", + "quote": " from better_memory._common import resolve_home\n from better_memory.mcp._util import resolve_session_id", + "title": "Storage layer imports the MCP transport package to resolve session ids", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-storage-layer-imports-the-mcp-transport-package-to-resolve-sessi-2026-09-09" + }, + "21a5a862aefe4c50": { + "family": "doc-drift", + "file": "website/architecture.md", + "line_start": 102, + "quote_hash": "04759b2a87b67ef255ce8f4352360fb90cc97407", + "quote": "**CLAUDE.md drift sentinel \u2014 retired.** SessionStart no longer runs a standalone sentinel that scanned `~/.claude/CLAUDE.md` for stale tool-parameter references (`better_memory/hooks/_claude_md_sentinel.py`, deleted). See [Self-managing wiring](#self-managing-wiring) above: the retrieve/reinforce/synthesize/record protocol text is now a managed block (`manifest.CLAUDE_MD_BLOCK`) that `better-memory setup` / `doctor --fix` / the session-start autocheck (`better_memory.setup.autocheck.maybe_repair`, wired into `hooks/session_bootstrap.py`) keep byte-identical to the canonical text, so drift is repaired outright rather than merely flagged. `better_memory/skills/CLAUDE.snippet.md` (used for non-Claude-Code MCP integrations) remains behavioural instructions only (\"pass a task-describing query when you begin a task\", \"credit with evidence\") and never enumerates parameter names or types, so it can't drift the way the retired sentinel used to detect.", + "title": "architecture.md asserts CLAUDE.snippet.md never enumerates parameters; the file ", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "24efba3bae72d807": { + "family": "test-gaps", + "file": "pyproject.toml", + "line_start": 51, + "quote_hash": "df3c6ac16f86c3901c5fc85d8f3932082d7545bd", + "quote": "addopts = \"-m 'not integration'\"\nmarkers = [\n \"integration: marks tests as integration tests (require external services)\",\n \"e2e: end-to-end clean-slate smoke tests (hermetic)\",", + "title": "tests/integration excluded by default addopts and never run in CI", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "251c4b6d14efdf59": { + "family": "duplication", + "file": "better_memory/services/reflection.py", + "line_start": 1551, + "quote_hash": "389389247b0423b5f26706e80b897ea2b66310a7", + "quote": " row = self._conn.execute(\n \"SELECT status FROM reflections WHERE id = ?\", (reflection_id,)\n ).fetchone()\n if row is None:\n raise ValueError(f\"Reflection not found: {reflection_id}\")\n status = row[\"status\"]", + "title": "Four ReflectionService lifecycle methods repeat the same status-guard/UPDATE ske", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "285a342b6cd70aec": { + "family": "duplication", + "file": "better_memory/services/relevant.py", + "line_start": 115, + "quote_hash": "6e5cdcb4cfab60d5e70b3b28aeae583b4b634b91", + "quote": " present_ranks = [prior_rank[c[\"id\"]]]\n if c[\"bm_rank\"] is not None:\n present_ranks.append(c[\"bm_rank\"])\n score = sum(1.0 / (_RRF_K + rank) for rank in present_ranks)", + "title": "RRF rank fusion hand-rolled in four modules with the same 1/(k+rank) formula", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "2cb14057f1787d1a": { + "family": "complex-units", + "file": "better_memory/cli/agentcore.py", + "line_start": 989, + "quote_hash": "95bd2cc98e0bd2df8a5187f3c5989d9fde66105b", + "quote": "def _handle_migrate(args: argparse.Namespace) -> int:\n from better_memory.storage import agentcore_migrate as _mig\n\n home = _resolve_home(args.home)\n\n includes = {s.strip() for s in args.include.split(\",\") if s.strip()}", + "title": "_handle_migrate is a 263-line CLI handler with 30 branches and 10 exits", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "2ec05b5275d04ec3": { + "family": "error-masking", + "file": "better_memory/storage/agentcore.py", + "line_start": 2444, + "quote_hash": "99886f22fbd990f8f728cbf0252babb38ef8d1ea", + "quote": " except Exception: # noqa: BLE001 - step (b) is best-effort, per-item\n # A local-ledger op raised (e.g. `database is locked` from\n # a concurrent UI writer past the 5000ms busy_timeout).", + "title": "Rating sweep drops entries silently: ledger failure counted in neither applied n", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-rating-sweep-drops-entries-silently-ledger-failure-counted-in-ne-2026-09-09" + }, + "2fbd2a81749c12b7": { + "family": "complex-units", + "file": "better_memory/cli/agentcore.py", + "line_start": 1386, + "quote_hash": "d0fb1e67a58642e4e14fc32e8d0d114900677776", + "quote": "def _execute_kind(\n conn: Any,\n data: Any,\n kind: str,\n *,\n memory_id: str,", + "title": "_execute_kind carries the highest complexity in the repo (31) over three wire ph", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "35be57b1268ea60a": { + "family": "dead-code", + "file": "better_memory/storage/protocol.py", + "line_start": 274, + "quote_hash": "eee4cc74c7f33c62ab2592ecd3b48459d4015e2b", + "quote": " def open_background_episode(\n self,\n *,\n session_id: str,\n project: str,\n ) -> str:", + "title": "StorageBackend episode lifecycle API has no production caller", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "35d1b704585c62a9": { + "family": "migration", + "file": "better_memory/config.py", + "line_start": 227, + "quote_hash": "8f16d1220c118a301a36de0db9e9ae0e05576d38", + "quote": " # NOTE: context_min_hits is DEPRECATED. The evidence-gated scorer in\n # services/relevant.py (BM25 qualifiers, with a keyword-hit fallback\n # when no FTS substrate is available -- or the backend's\n # relevance_ranks in agentcore mode) replaced the old pure\n # keyword-hits floor; contextual_inject.py no longer reads this\n # field. Kept for back-compat with any external", + "title": "context_min_hits marked DEPRECATED but still a Config field resolved every get_c", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "38846b024a776068": { + "family": "dead-code", + "file": "better_memory/ui/queries.py", + "line_start": 581, + "quote_hash": "e3697a96aaa73dc14cb0bdcd9f069fe10b169b1a", + "quote": "def reflection_distinct_projects(conn: sqlite3.Connection) -> list[str]:\n \"\"\"Return all distinct project values in the reflections table, sorted.\n\n Powers the Project dropdown on the reflections page.\n \"\"\"", + "title": "ui/queries.reflection_distinct_projects superseded by backend.distinct_projects", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "388d44a4fa5f08d4": { + "family": "architecture", + "file": "better_memory/cli/agentcore.py", + "line_start": 908, + "quote_hash": "f2b8160657744ea7c933280cd8bc0b28bace98e4", + "quote": "def _eligible_reflection_rows(conn: Any, project: str | None) -> list[Any]:\n if project:\n cur = conn.execute(\n \"SELECT * FROM reflections \"\n \"WHERE status IN ('pending_review', 'confirmed') \"\n \" AND (project = ? OR scope = 'general')\",", + "title": "SQLite->AgentCore migration logic and its raw SQL live in the CLI layer", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "3f4580d8f0c62c8a": { + "family": "test-gaps", + "file": "better_memory/cli/agentcore.py", + "line_start": 883, + "quote_hash": "11c81a2e1f6cc4f8201d7e6896459f6f296444cf", + "quote": "def _acquire_migration_lock(home: Path) -> int:\n \"\"\"Single-run advisory lock: a ``/agentcore_migration.lock`` file\n created O_EXCL. Raises ``FileExistsError`` if a run is already in flight.\"\"\"", + "title": "AgentCore migrate concurrency lock has no test on either branch", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "403d5902f4213a5d": { + "family": "god-classes", + "file": "better_memory/cli/agentcore.py", + "line_start": 126, + "quote_hash": "32a134dbff16a3a69b4ba549809e34c24c6faa46", + "quote": "def handle(args: argparse.Namespace) -> int:\n if args.subcommand == \"init\":\n return _handle_init(args)\n if args.subcommand == \"status\":\n return _handle_status(args)\n if args.subcommand == \"smoke\":", + "title": "cli/agentcore.py owns provisioning, smoke, migration and raw storage SQL", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "422536b4768f74e9": { + "family": "duplication", + "file": "better_memory/storage/agentcore.py", + "line_start": 468, + "quote_hash": "00cd10c0d8a997b5d30165def544d51b4cd4c114", + "quote": " summaries: list[dict[str, Any]] = []\n token: str | None = None\n while len(summaries) < max_results:\n kwargs: dict[str, Any] = {\n \"memoryId\": self._cfg.episodic.memory_id,\n \"namespace\": namespace,", + "title": "list_memory_records nextToken pagination loop copied four times", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-list-memory-records-nexttoken-pagination-loop-copied-four-times-2026-09-09" + }, + "4bf39eeaa3f18261": { + "family": "architecture", + "file": "better_memory/hooks/contextual_inject.py", + "line_start": 145, + "quote_hash": "23b405cea00157f96ebc1f9ca348b04e9e862806", + "quote": " items = retrieve_relevant(\n backend, query=query, project=project,\n conn=conn if cfg.storage_backend == \"sqlite\" else None,\n max_items=cfg.context_max_items,", + "title": "Backend selection leaks past the factory into hooks via storage_backend string t", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "4cba0399f66dd81c": { + "family": "dead-code", + "file": "better_memory/storage/agentcore.py", + "line_start": 135, + "quote_hash": "4b2dbc57840c2d34322c5a88860e4962aa31aac8", + "quote": " self._control = control_client", + "title": "AgentCoreBackend stores a control_client it never reads", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-agentcorebackend-stores-a-control-client-it-never-reads-2026-09-09" + }, + "545d4b1cdfd04d51": { + "family": "pipeline-infra", + "file": ".github/workflows/typecheck.yml", + "line_start": 25, + "quote_hash": "a571806a47ff7de73f4f0994dc3a50c6e321f53b", + "quote": "typecheck:", + "title": "CI workflow gaps in .github/workflows/typecheck.yml", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "58f99a90bcb300e5": { + "family": "dead-code", + "file": "better_memory/config.py", + "line_start": 227, + "quote_hash": "8f16d1220c118a301a36de0db9e9ae0e05576d38", + "quote": " # NOTE: context_min_hits is DEPRECATED. The evidence-gated scorer in\n # services/relevant.py (BM25 qualifiers, with a keyword-hit fallback\n # when no FTS substrate is available -- or the backend's\n # relevance_ranks in agentcore mode) replaced the old pure\n # keyword-hits floor; contextual_inject.py no longer reads this\n # field. Kept for back-compat with any external", + "title": "Config.context_min_hits is documented DEPRECATED and read by no consumer", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "5ba6b643a92794ef": { + "family": "error-masking", + "file": "better_memory/services/spool.py", + "line_start": 278, + "quote_hash": "1b36b0c7ff16f95b52b8ed0cae5bd68c4d258219", + "quote": " except ValueError:\n # No active episode for this session \u2014 stale/duplicate marker.\n pass\n except Exception: # noqa: BLE001 \u2014 drain side-effects must not fail drain\n pass", + "title": "Spool drain swallows episode-close failures, leaving episodes open with no recor", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "5cef5c4bbfbe1b9a": { + "family": "half-finished", + "file": ".claude/skills/start-better-memory-ui/SKILL.md", + "line_start": 8, + "quote_hash": "cdbb50ac7b3946f72257fd0313e2ff67d13c25f7", + "quote": "The MCP tool `mcp__better-memory__memory_start_ui` is a stub that returns \"UI not yet implemented\" \u2014 but the UI itself is fully built. Launch it directly.", + "title": "Shipped skill still says memory_start_ui is a stub returning 'UI not yet impleme", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "614ee6fa1d4901d2": { + "family": "half-finished", + "file": "better_memory/storage/agentcore.py", + "line_start": 2522, + "quote_hash": "47ea4189ce4bd44501b14175fb6aee260196e6ac", + "quote": " \"\"\"Best-effort CreateEvent receipt for a successful rating sweep\n (design \u00a73.2/\u00a74 \"Ratings event (C-lite)\"). extractionMode='SKIP'\n keeps this out of AgentCore's built-in episodicMemoryStrategy\n extraction \u2014 it is a durable, team-visible receipt only; the\n read/UI path is deferred to a future PR. Callers wrap this in a", + "title": "AgentCore ratings receipt events are written on every sweep but nothing reads th", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "647745a87d0cf367": { + "family": "pipeline-infra", + "file": ".github/workflows/docs.yml", + "line_start": 24, + "quote_hash": "2ed9e49ab71be45cee16f6627e2d0ee358dc4089", + "quote": "build:", + "title": "CI workflow gaps in .github/workflows/docs.yml", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "66baa1db25e1caac": { + "family": "half-finished", + "file": "tests/e2e_meta/test_marker_wiring.py", + "line_start": 105, + "quote_hash": "ba1ad3d9fb868d9a546609f52c9a5081e3d0ebec", + "quote": " \"\"\"T3 exists and is collectable when explicitly requested (step 3).\"\"\"\n if not LIVE_T3.exists():\n pytest.skip(\"tests/integration/test_agentcore_live_e2e.py not implemented yet (task 12)\")", + "title": "Stale 'not implemented yet (task 12)' skip guard in the marker-wiring meta test", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "67040750d4ec12ea": { + "family": "pipeline-infra", + "file": ".github/workflows/bugbot.yml", + "line_start": 16, + "quote_hash": "47278312a5c724f5a314a1d354e7cc29a6e54d3a", + "quote": "bugbot:", + "title": "CI workflow gaps in .github/workflows/bugbot.yml", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "678b00e43c23d0c7": { + "family": "error-masking", + "file": "better_memory/cli/agentcore.py", + "line_start": 253, + "quote_hash": "603702e342df4c860ebd7df45a2aee88a497b12d", + "quote": " try:\n memory = control.get_memory(memoryId=summary[\"id\"])[\"memory\"]\n except Exception:\n continue", + "title": "_find_existing_memory treats any GetMemory error as \"memory does not exist\"", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "69fb51b351dfa0ff": { + "family": "doc-drift", + "file": "docs/agentcore-ui/gaps/distinct-project-dropdown-enumeration.md", + "line_start": 8, + "quote_hash": "5c316630a17185646e23ee60a8a669fe2f0121b4", + "quote": "**Scope:** the project-selector dropdown that appears on the Observations tab and\nthe Reflections tab. Both are populated today by a raw `SELECT DISTINCT project`\nagainst local sqlite and have no direct AgentCore equivalent.", + "title": "agentcore-ui gap doc presents its own recommendation as unbuilt and cites stale ", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "724c2c9d55c9ae8e": { + "family": "half-finished", + "file": "better_memory/hooks/post_commit.py", + "line_start": 64, + "quote_hash": "b4387b0b83add0aceac22a219a33359d5d1ce65c", + "quote": " \"HEAD\",\n ],\n capture_output=True,\n text=True,\n check=True,\n )", + "title": "Post-commit hook runs git with no timeout; a stalled git blocks every commit", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "77f4c447b08deb6a": { + "family": "duplication", + "file": "better_memory/ui/app.py", + "line_start": 410, + "quote_hash": "09b242d957c5e969d94c286df37d12bd560601d1", + "quote": " if _reflection_drawer_detail(app, id) is None:\n abort(404)\n try:\n app.extensions[\"backend\"].retire_reflection(reflection_id=id)\n except (ValueError, RuntimeError) as exc:\n return (", + "title": "Eight UI mutation routes repeat the same guard / error-card / trigger body", + "tier": "B", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "788f833935615c78": { + "family": "complex-units", + "file": "better_memory/services/reflection.py", + "line_start": 1006, + "quote_hash": "44786a60c7dddb72fe90cf4e8a210b2582540c4e", + "quote": " (action.source_id,),\n ).fetchone()\n if src is None:\n continue\n if src[\"status\"] in (\"retired\", \"superseded\"):\n continue", + "title": "_apply_merge runs six skip guards plus counter math in one 150-line loop body", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "7c3d1c55425429db": { + "family": "half-finished", + "file": "tests/mcp/test_start_ui_tool.py", + "line_start": 48, + "quote_hash": "be0265d99e2fe9ddcf6aa2782aa81300b4194ffe", + "quote": " Mirrors the exact code the real handler runs. If the handler body\n in server.py drifts from this mirror, this test still passes \u2014 the\n registration test catches the misroute, and code review catches the\n drift. Combined coverage is sufficient for this thin passthrough.", + "title": "start_ui handler test mirrors the handler body instead of invoking it, by admiss", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "7e6262e29bf17c30": { + "family": "test-gaps", + "file": "better_memory/ui/app.py", + "line_start": 602, + "quote_hash": "b2daee00afa8f15a115226cfbe27a41fef9f62a9", + "quote": " return render_template(\n \"observations.html\",\n active_tab=\"observations\",\n projects=queries.observation_distinct_projects(conn),\n )", + "title": "Observations Project dropdown source never asserted, unlike Reflections", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "8209c31e1a6bde54": { + "family": "god-classes", + "file": "better_memory/storage/agentcore.py", + "line_start": 120, + "quote_hash": "1374f9456880b22931d41fcd831d500b1a51457e", + "quote": "class AgentCoreBackend:\n \"\"\"boto3-backed StorageBackend implementation.\"\"\"", + "title": "AgentCoreBackend owns reflections, semantics, episodes, ratings and a local DB", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "84f960eb966c238c": { + "family": "architecture", + "file": "better_memory/storage/sqlite.py", + "line_start": 350, + "quote_hash": "d55fbe0effd9bb6096d9a6cc702ad2dce6128238", + "quote": " def reflection_get(self, *, reflection_id: str) -> dict[str, Any] | None:\n from dataclasses import asdict\n\n from better_memory.ui import queries\n\n row = queries.reflection_row(self._conn, reflection_id=reflection_id)", + "title": "storage <-> ui package cycle: SqliteBackend implements reflection reads via ui/q", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "85315a5a5ebc8af3": { + "family": "migration", + "file": "better_memory/config.py", + "line_start": 252, + "quote_hash": "5f29764f3f250537e19cee4a3b6ffa16b6da9f9a", + "quote": "def _resolve_inject_mode() -> Literal[\"deferred\", \"legacy\"]:\n raw = (os.environ.get(\"BETTER_MEMORY_INJECT_MODE\") or \"legacy\").strip().lower()\n # Fail-safe: anything unrecognised means today's behaviour.\n return \"deferred\" if raw == \"deferred\" else \"legacy\"", + "title": "Two SessionStart render paths: config defaults to legacy, setup installs deferre", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "857381d541adbaf9": { + "family": "pipeline-infra", + "file": ".github/workflows/ui-tests.yml", + "line_start": 25, + "quote_hash": "859a0f5fb82a0d997c4f8115dd0c788eb691df00", + "quote": "ui-tests:", + "title": "CI workflow gaps in .github/workflows/ui-tests.yml", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "8767181c359d29cc": { + "family": "doc-drift", + "file": "website/mcp-tools.md", + "line_start": 59, + "quote_hash": "b044c6a3f4c74435f767178d59660a437d0750a2", + "quote": "| `id` | string | yes |\n| `outcome` | `success` / `failure` | yes |", + "title": "website/mcp-tools.md tables contradict the live MCP tool schemas and wire payloa", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "897297b7f1d46208": { + "family": "complex-units", + "file": "scripts/agentcore_smoke.py", + "line_start": 228, + "quote_hash": "e320ca53cbe1a6af4a2210f754c53caa7b5e8d00", + "quote": "def main() -> int:\n boto_config = BotoConfig(\n region_name=REGION,\n retries={\"mode\": \"standard\", \"max_attempts\": 5},\n )\n control = boto3.client(\"bedrock-agentcore-control\", config=boto_config)", + "title": "scripts/agentcore_smoke.py main() is a 331-line procedure nested seven levels de", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "8b8c6e75ea5143e2": { + "family": "dependency-debt", + "file": "better_memory/ui/__main__.py", + "line_start": 15, + "quote_hash": "92feeefdcb754b5c11ef7f0ba27bd6e559355818", + "quote": "from werkzeug.serving import make_server", + "title": "werkzeug imported directly but never declared; arrives only as a Flask transitiv", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "8dd59c75f0d820c6": { + "family": "test-gaps", + "file": "pyproject.toml", + "line_start": 31, + "quote_hash": "edae16d5a058fdb105eba793272caadfe18dc244", + "quote": "dev = [\n \"pytest\",\n \"pytest-asyncio\",\n \"pytest-playwright\",\n \"ruff\",\n \"pyright\",", + "title": "No coverage measurement configured anywhere in the project", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "9189467e4bb39f2b": { + "family": "complex-units", + "file": "better_memory/services/session_bootstrap.py", + "line_start": 262, + "quote_hash": "fd987927ba2467423ddb1304595ad3265992b688", + "quote": " if get_config().inject_mode == \"deferred\":\n general_only = [m for m in semantic if m.scope == \"general\"]\n deferred_now = self._clock()\n n_refl = sum(reflections_counts.values())\n n_sem = semantic_count\n index_line = (", + "title": "SessionBootstrapService.bootstrap holds two full render paths in one 177-line me", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "9b2a173ced74a3d7": { + "family": "test-gaps", + "file": "better_memory/db/migrations/0013_ignored_counters.sql", + "line_start": 29, + "quote_hash": "15ca9ade1d574d8aa41d717626e0f4aa961bfdb2", + "quote": "UPDATE reflections SET\n times_ignored = COALESCE((\n SELECT COUNT(DISTINCT e.session_id)\n FROM session_memory_exposure e\n WHERE e.memory_kind = 'reflection'", + "title": "Migration 0013 times_ignored backfill has no test; siblings all have one", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "9e390a5527cb72de": { + "family": "doc-drift", + "file": "better_memory/setup/manifest.py", + "line_start": 107, + "quote_hash": "69982feea7efe03dc63747689d3709c86bfafe21", + "quote": "MANAGED_ENV: dict[str, str] = {\"BETTER_MEMORY_INJECT_MODE\": \"deferred\"}", + "title": "Docs site states legacy is the bootstrap default while setup installs deferred e", + "tier": "B", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "9e3cb2ba54d821bd": { + "family": "duplication", + "file": "better_memory/hooks/contextual_inject.py", + "line_start": 86, + "quote_hash": "934221e31c92014b43fb438f00bc5f7837acb6cd", + "quote": " raw = \"\"\n try:\n raw = sys.stdin.read(_MAX_STDIN_BYTES + 1)\n except BaseException: # noqa: BLE001 \u2014 hooks never fail\n pass", + "title": "Hook stdin-read and output-envelope boilerplate copied, byte cap already drifted", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "a8793c1b65faeda7": { + "family": "duplication", + "file": "better_memory/mcp/handlers/semantics.py", + "line_start": 115, + "quote_hash": "674cd07360ddf56469dfc6e2d0c83fe0bfe6fc8f", + "quote": " self._remote.semantic_update_text(\n id=args[\"id\"], content=args[\"content\"]\n )\n return [TextContent(type=\"text\", text=json.dumps({\"ok\": True}))]\n self._semantic.update_text(id=args[\"id\"], content=args[\"content\"])\n return [TextContent(type=\"text\", text=json.dumps({\"ok\": True}))]", + "title": "MCP handlers fork remote/sqlite and duplicate the call plus payload in each bran", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "af9365501464d427": { + "family": "architecture", + "file": "better_memory/ui/app.py", + "line_start": 679, + "quote_hash": "a8e4fb40471c44a699e0618dd82c1816ca2896c6", + "quote": " conn = app.extensions[\"db_connection\"]\n recent_ratings = conn.execute(\n \"\"\"\n SELECT e.rated_at, e.memory_kind, e.memory_id, e.classification,\n e.evidence,\n COALESCE(r.title, s.content) AS display", + "title": "UI /diagnostics route joins memory-content tables on the operational connection", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "b0d218dcf72befd7": { + "family": "half-finished", + "file": "better_memory/storage/agentcore.py", + "line_start": 1115, + "quote_hash": "7af2e741d3fec436297fd607b26905b0676b14bf", + "quote": " \"\"\"List raw events from the CURRENT session as observations. Cross-\n session enumeration is deferred (ListEvents requires sessionId).\n Same lazy session-id re-resolution contract as ``observe``.\"\"\"", + "title": "AgentCore retrieve_observations silently returns only the current session", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-agentcore-retrieve-observations-silently-returns-only-the-curren-2026-09-09" + }, + "b326fb5357e1811f": { + "family": "security", + "file": "scripts/setup.sh", + "line_start": 8, + "quote_hash": "aadc768ad89a051c4a2497decf2bc608531edf2b", + "quote": " curl -LsSf https://astral.sh/uv/install.sh | sh", + "title": "Bootstrap scripts pipe a remote installer straight into a shell", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "b542869562d70cc7": { + "family": "dead-code", + "file": "better_memory/services/memory_rating.py", + "line_start": 21, + "quote_hash": "e9095fceaba8f828bbc9c3a00b9433136ad64930", + "quote": "Kind = Literal[\"reflection\", \"semantic\"]\nClassification = Literal[\"cited\", \"shaped\", \"ignored\", \"misled\", \"overlooked\"]\nCreditClassification = Literal[\"cited\", \"shaped\", \"misled\", \"overlooked\"]\nSkipReason = Literal[", + "title": "Four unused type aliases at the top of services/memory_rating.py", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "b71e4439a074735e": { + "family": "error-masking", + "file": "better_memory/mcp/server.py", + "line_start": 183, + "quote_hash": "b919cf83494aea6f7ac5ce11d4ed54ac1f4b7637", + "quote": " try:\n knowledge.reindex()\n except Exception: # noqa: BLE001 \u2014 best-effort startup hook\n pass", + "title": "MCP server startup swallows knowledge reindex failure; stale index served silent", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "bc106246755c578a": { + "family": "half-finished", + "file": "better_memory/services/episode.py", + "line_start": 183, + "quote_hash": "0c7832279654bcc7e6c50bfb64226b7374eb1259", + "quote": " # Supersede close: spec \u00a73 distinguishes partial vs\n # no_outcome based on success signals (commit / plan-\n # complete). Phase 2 has no hook infrastructure yet, so\n # we always write no_outcome. Phase 4 introduces the\n # hooks and upgrades this to 'partial' when signals fired.", + "title": "Episode supersede still hardcodes no_outcome; the Phase-4 'partial' upgrade neve", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "c06b843ed6f0635d": { + "family": "doc-drift", + "file": "website/contributing.md", + "line_start": 70, + "quote_hash": "b2561728099e3cc5c854a1fbf4d8e8c047f39ecb", + "quote": "See `CLAUDE.md` for the full discipline.", + "title": "contributing.md points at CLAUDE.md for process discipline; CLAUDE.md contains o", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "c0a031e0c37feff8": { + "family": "complex-units", + "file": "better_memory/storage/agentcore.py", + "line_start": 390, + "quote_hash": "4f177821ae448049e18e4636981fd7b7ac15e289", + "quote": " def _fetch_reflection_buckets(\n self,\n *,\n actor_id: str,\n limit_per_bucket: int,\n tech: str | None = None,", + "title": "_fetch_reflection_buckets is 246 lines of fan-out, parse, rank, fuse and fill", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "c332abd4c27ee51f": { + "family": "doc-drift", + "file": "website/contributing.md", + "line_start": 27, + "quote_hash": "91a74b9595799217b9323f994ac26598b967fac7", + "quote": "Both are enforced in CI:\n\n- **`.github/workflows/ui-tests.yml`** \u2014 Playwright UI test suite.\n- **`.github/workflows/typecheck.yml`** \u2014 Pyright on `better_memory/` and `tests/`.\n- **`.github/workflows/bugbot.yml`** \u2014 Claude BugBot review on every PR.", + "title": "contributing.md claims ruff is enforced in CI; no workflow runs it", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "c42059bdbaa5f5e3": { + "family": "complex-units", + "file": "better_memory/ui/app.py", + "line_start": 40, + "quote_hash": "2b514d725eedc5e41a374bc8d4c69760b44dbdbe", + "quote": "def create_app(\n *,\n inactivity_timeout: float = 1800.0,\n inactivity_poll_interval: float = 30.0,\n start_watchdog: bool = True,\n db_path: Path | None = None,", + "title": "create_app is a 739-line factory holding 39 route closures over shared scope", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "c599325017f87069": { + "family": "error-masking", + "file": "better_memory/storage/agentcore.py", + "line_start": 386, + "quote_hash": "6da6ebe0153e1dfcac97ca88854a1b7a42635c1b", + "quote": " self._local_conn.commit()\n except Exception: # noqa: BLE001 - exposures must never block retrieve\n pass", + "title": "Exposure-ledger writes swallowed in two places: served memories never become rat", + "tier": "A", + "status": "promoted", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": "chore-exposure-ledger-writes-swallowed-in-two-places-served-memories-n-2026-09-09" + }, + "cc915dbdeeb29ada": { + "family": "doc-drift", + "file": "better_memory/setup/manifest.py", + "line_start": 152, + "quote_hash": "65ba944ab1d8e4cd0f8837bf5fee22eb8ef5d01d", + "quote": "## Reinforce: After Using a Memory\n\nWhen a retrieved memory materially helped or misled you, reinforce it:\n- `mcp__better-memory__memory_record_use` with the observation `id` and `outcome` (`success` or `failure`)", + "title": "Managed CLAUDE.md block directs reinforcement to record_use, a no-op for retriev", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d26de4b2ed05c93c": { + "family": "error-masking", + "file": "better_memory/services/reflection.py", + "line_start": 1486, + "quote_hash": "f8ea08e16cb7cd085c6c624c5b599eadeb93906f", + "quote": " self._conn.commit()\n except BaseException:\n pass", + "title": "Diagnostics counter for session_id_missing hidden behind bare `except BaseExcept", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d29c1d4581eeccfc": { + "family": "dead-code", + "file": "better_memory/cli/install_hooks.py", + "line_start": 1, + "quote_hash": "98ff3f73e364e46fa4051578a8a1fd8a249fec7b", + "quote": "\"\"\"DEPRECATED: superseded by `better-memory setup` (better_memory/cli/setup_cmd.py).\n\nKept as a thin shim: parses the legacy flags, ignores them (machine params\nare now auto-detected), and delegates to the setup engine.", + "title": "Deprecated cli/install_hooks.py shim has no in-repo caller or console script", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d4978286f73aa058": { + "family": "half-finished", + "file": "better_memory/config.py", + "line_start": 227, + "quote_hash": "8f16d1220c118a301a36de0db9e9ae0e05576d38", + "quote": " # NOTE: context_min_hits is DEPRECATED. The evidence-gated scorer in\n # services/relevant.py (BM25 qualifiers, with a keyword-hit fallback\n # when no FTS substrate is available -- or the backend's\n # relevance_ranks in agentcore mode) replaced the old pure\n # keyword-hits floor; contextual_inject.py no longer reads this\n # field. Kept for back-compat with any external", + "title": "Deprecated context_min_hits knob still resolved, and still advertised in the mod", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d7a4d6195ef1810e": { + "family": "migration", + "file": "better_memory/ui/queries.py", + "line_start": 581, + "quote_hash": "8994ae477beaa7d0fc47e825de2c213e28ffa6a8", + "quote": "def reflection_distinct_projects(conn: sqlite3.Connection) -> list[str]:\n \"\"\"Return all distinct project values in the reflections table, sorted.\n\n Powers the Project dropdown on the reflections page.\n \"\"\"\n return [", + "title": "reflection_distinct_projects duplicates SqliteBackend.distinct_projects with no ", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d7d9068394318935": { + "family": "god-classes", + "file": "better_memory/storage/protocol.py", + "line_start": 1, + "quote_hash": "bbad795e3233041a904236415be86abc722949bc", + "quote": "\"\"\"StorageBackend Protocol.\n\nFat protocol with high-level operations. Both SqliteBackend (Plan 1) and\nAgentCoreBackend (Plan 2) implement it. Synthesis methods are sqlite-only \u2014", + "title": "StorageBackend fat protocol forces no-op methods and 7 capability flags", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "d853679a3befaa94": { + "family": "test-gaps", + "file": "better_memory/cli/agentcore.py", + "line_start": 249, + "quote_hash": "1246e6f173321d8f967fa575688d4f6627df0f01", + "quote": " for page in paginator.paginate():\n for summary in page.get(\"memories\", []):\n if summary.get(\"status\") == \"DELETING\":\n continue\n try:\n memory = control.get_memory(memoryId=summary[\"id\"])[\"memory\"]", + "title": "_find_existing_memory DELETING-skip and get_memory-error branches untested", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "df42541a4a5ed199": { + "family": "security", + "file": "better_memory/services/ui_launcher.py", + "line_start": 42, + "quote_hash": "4ab365fdf1ddb87b7c4702ab2ec5f61a186aff04", + "quote": " with urllib.request.urlopen( # noqa: S310 \u2014 local-only loopback URL\n probe, timeout=_HEALTHZ_TIMEOUT_SEC\n ) as response:", + "title": "noqa: S310 on urlopen asserts a loopback URL the code never checks", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "e4420347ddb39483": { + "family": "test-gaps", + "file": ".github/workflows/ui-tests.yml", + "line_start": 45, + "quote_hash": "8d7fc17c1efb5320c5d1212c5851e82e6fd840e5", + "quote": " - name: Run UI tests\n run: uv run pytest tests/ui/ -v --tb=short", + "title": "No CI job runs the 113 non-UI test modules; only tests/ui/ gates a PR", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "e4e53cd88b8e5d4c": { + "family": "architecture", + "file": "better_memory/storage/sqlite.py", + "line_start": 67, + "quote_hash": "8e6b0f9cfc8ff0a8137a2530599978904e466951", + "quote": " @property\n def supports_synthesis(self) -> bool:\n return True\n\n @property\n def supports_episodes(self) -> bool:\n return True", + "title": "Seven StorageBackend capability flags encode one bit: sqlite or not", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "e7d15e528eef61b5": { + "family": "duplication", + "file": "better_memory/services/exposure_log.py", + "line_start": 25, + "quote_hash": "08a2926c5dee8e5c00b91622ec3946419a928a7e", + "quote": " ``MemoryRatingService._apply_one``. Copied, not rewired \u2014 the sqlite\n rating service keeps its own inline copy; this one is for the agentcore\n backend (and any future caller) to share.", + "title": "session_memory_exposure ledger SQL copied across 6 sites despite exposure_log.py", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "e9ca0604989ebce0": { + "family": "doc-drift", + "file": ".claude/skills/start-better-memory-ui/SKILL.md", + "line_start": 6, + "quote_hash": "b5b9e4df69e3744ff9fea51200abf0151e561597", + "quote": "# Start better-memory UI\n\nThe MCP tool `mcp__better-memory__memory_start_ui` is a stub that returns \"UI not yet implemented\" \u2014 but the UI itself is fully built. Launch it directly.", + "title": "memory.start_ui documented as an unimplemented stub in the shipped skill and REA", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "ecd59eb0bc15610a": { + "family": "migration", + "file": "better_memory/cli/install_hooks.py", + "line_start": 1, + "quote_hash": "98ff3f73e364e46fa4051578a8a1fd8a249fec7b", + "quote": "\"\"\"DEPRECATED: superseded by `better-memory setup` (better_memory/cli/setup_cmd.py).\n\nKept as a thin shim: parses the legacy flags, ignores them (machine params\nare now auto-detected), and delegates to the setup engine.", + "title": "cli/install_hooks.py deprecated shim unreachable from the CLI, no removal date", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "ed1a29f05192947a": { + "family": "dead-code", + "file": "better_memory/config.py", + "line_start": 183, + "quote_hash": "295c75e16f1961733ce72259bae0a402872adc40", + "quote": "def _resolve_str(env_var: str, default: str) -> str:\n return os.environ.get(env_var, default)", + "title": "config._resolve_str is an unused env-var helper", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "ee90cbb9a638b279": { + "family": "complex-units", + "file": "better_memory/cli/agentcore.py", + "line_start": 362, + "quote_hash": "ccbc34c90fdc04ab61c154e39c2534d5854002ce", + "quote": " except Exception as exc:\n # ValidationException on the name regex is the most common\n # operator error \u2014 surface the boto3 message + a pointer to the\n # troubleshooting page rather than dumping a raw ClientError trace.\n code = \"\"\n try:", + "title": "_handle_init interleaves create, orphan cleanup and 60 lines of guidance printin", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "efccfcefddd5d264": { + "family": "dead-code", + "file": "better_memory/config.py", + "line_start": 252, + "quote_hash": "5f29764f3f250537e19cee4a3b6ffa16b6da9f9a", + "quote": "def _resolve_inject_mode() -> Literal[\"deferred\", \"legacy\"]:\n raw = (os.environ.get(\"BETTER_MEMORY_INJECT_MODE\") or \"legacy\").strip().lower()\n # Fail-safe: anything unrecognised means today's behaviour.\n return \"deferred\" if raw == \"deferred\" else \"legacy\"", + "title": "inject_mode keeps two full bootstrap render paths past scheduled legacy deletion", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "f17b018f7d071f4f": { + "family": "test-gaps", + "file": "scripts/e2e_mutation_smoke.py", + "line_start": 36, + "quote_hash": "3c28d2c243dfa046baccc4534e42b559224b03f5", + "quote": " python scripts/e2e_mutation_smoke.py --check-only # CI: patches apply cleanly", + "title": "Mutation-smoke suite-power gate never runs in CI; M2.patch no longer applies", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "f5908be2ca4460d4": { + "family": "duplication", + "file": "better_memory/hooks/observer.py", + "line_start": 78, + "quote_hash": "3506c7a9a24dddb0867d6703e374b8497885df98", + "quote": " final_path = spool_dir / file_name\n tmp_path = final_path.with_suffix(final_path.suffix + \".tmp\")\n tmp_path.write_text(json.dumps(data), encoding=\"utf-8\")\n os.replace(tmp_path, final_path)", + "title": "Atomic spool-file write block duplicated verbatim in three hooks", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "f836695b99600e74": { + "family": "error-masking", + "file": "pyproject.toml", + "line_start": 61, + "quote_hash": "47f8432b3a04f3366059061e2d000e2c3757b59a", + "quote": "[tool.ruff.lint]\nselect = [\"E\", \"F\", \"I\", \"UP\", \"B\"]", + "title": "61 `# noqa: BLE001` suppressions are inert: ruff's select list omits BLE and no ", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "f87b5464a0c2f321": { + "family": "duplication", + "file": "better_memory/storage/agentcore.py", + "line_start": 449, + "quote_hash": "a34a1d6f994fd29e0629927c87a4ca4de067e41f", + "quote": " project_ns = resolve_namespace(actor_id, \"reflections\")\n general_ns = resolve_namespace(\"general\", \"reflections\")", + "title": "project+general namespace fan-out block repeated four times in agentcore backend", + "tier": "A", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "fb10a6b7008b0ac1": { + "family": "migration", + "file": "better_memory/_common.py", + "line_start": 22, + "quote_hash": "5aefc110928fb50ac9a48fce4d72ea96972a3463", + "quote": " Reads ``CLAUDE_SESSION_ID`` first (kept as the primary name for\n back-compat), then ``CLAUDE_CODE_SESSION_ID`` (the name Claude Code\n actually exports). The shared resolution order makes hook-written\n events and MCP-written observations agree on the same session id.", + "title": "Session-id resolver prefers the back-compat env name over the one Claude Code ex", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "fdd712dec5eaf0d2": { + "family": "complex-units", + "file": "better_memory/cli/agentcore.py", + "line_start": 620, + "quote_hash": "1152ef0c39bf4af3c990954df773e16446fd2c90", + "quote": " for attempt in range(1, 6):\n try:\n record = data.get_memory_record(\n memoryId=cfg.semantic.memory_id,\n memoryRecordId=real_id,\n )[\"memoryRecord\"]", + "title": "_handle_smoke is a 139-line linear AWS script inside one CLI handler", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + }, + "fe62b3636e46223b": { + "family": "migration", + "file": "better_memory/setup/manifest.py", + "line_start": 154, + "quote_hash": "e92e9e51ac30cf95c1a5d4929b2bc9db3ced7fbb", + "quote": "When a retrieved memory materially helped or misled you, reinforce it:\n- `mcp__better-memory__memory_record_use` with the observation `id` and `outcome` (`success` or `failure`)", + "title": "Two reinforcement idioms: installed CLAUDE.md says record_use, runtime footers s", + "tier": "C", + "status": "pending", + "first_seen": "2026-09-09", + "last_seen": "2026-09-09", + "reason": null, + "until": null, + "bundle": null + } + } +}