diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5d1b1..baefb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - CI: install `wikifier[mcp]` only on Python ≥3.10 (`mcp` has no 3.8/3.9 wheels). +- Regenerated committed `library.md` from a full `update-maps` so deleted 4.6.10 leftovers (`mcp/tools/{intel,status,workflow}.py`, `parsers/javascript/_parser.py`, `health.py`, `server_backup.py`) no longer appear in the file tree, Mermaid graph, or reverse-deps. +- `generate_library_md` drops cache keys / reverse-deps whose source is not a file on disk (stale cache cannot resurrect ghosts). +- File-tree captions prefer `*.wiki.md` purpose/role text; health *reasons* are audit stamps and are not copied as descriptions. +- `session_bootstrap`: re-read `cache_backend` after ACS persist so creating an empty SQLite stub does not leave `cache_backend: "none"`. Additive `cache_empty` / `cache_files_indexed` distinguish sqlite-empty from no store. + +### Added +- `tests/test_library_map_honesty.py`: fails if committed `library.md` names a path that is not a file on disk. + +### Changed +- Agent Protocol **v0.6.1**: 4.6.x additive field notes (readiness tiers, `map_paths`, ACS v1.3 `agent_signal`, `needs_mark_green`, sqlite-empty vs `cache_backend: none`). +- README / protocol language table: deep/ACS (Python, JS/TS) vs regex hint (Rust/Go/C/C++/C#/Java). ## [4.6.13] - 2026-08-27 diff --git a/CLAUDE.md b/CLAUDE.md index 5a9415b..da977c8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Wikifier is a **zero-dependency, agent-to-agent codebase wiki**: it gives AI agents a token-efficient, queryable map of a codebase (health matrix, dependency graph, per-file wiki summaries) so they can look things up instead of re-reading full sources. The human layer (`index.html` dashboard) is strictly secondary — a read-only viewer of the same artifacts. It is deliberately NOT a general human documentation tool. -**This repo dogfoods itself.** Wikifier runs on its own source, and you are expected to follow its agent protocol when working here (see below). The authoritative agent contract is `skills/run.md` (Agent Protocol v0.6 — package 4.6.x) — read it before substantive work. +**This repo dogfoods itself.** Wikifier runs on its own source, and you are expected to follow its agent protocol when working here (see below). The authoritative agent contract is `skills/run.md` (Agent Protocol v0.6.1 — package 4.6.x) — read it before substantive work. **USE WIKIFIER FIRST (non-negotiable in this repo, preferred on any managed target):** At session start call `session_bootstrap` (MCP or `python -m wikifier session-bootstrap`). Prefer Core daily tools (`list_core_tools`): bootstrap, `check_changes`, `prepare_edit`, `suggest_next_actions` (json `actions[]`), `record_change`, `mark_green`. Look up via map/wiki/deps before re-reading full sources. Selective work only (🔴 / actionable 🟡). Never skip `record_change` after edits. diff --git a/README.md b/README.md index f4c5ce3..dea2438 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,12 @@ Wikifier is an **agent-to-agent** tool: it builds a living map of a project (health matrix, dependency graph, short file summaries) and agents keep that map current as they work. Humans can peek via a small dashboard; the product is the agent loop, not a general docs site or IDE. -Works from small scripts to large monorepos. **Deep import/include maps** (zero-dep regex parsers): - -| Language | Extensions | Notes | -|----------|------------|--------| -| Python | `.py` | full ACS/CDIA path | -| JavaScript / TypeScript | `.js` `.ts` `.jsx` `.tsx` | barrels (BREE), dynamic/CDIA | -| Rust | `.rs` | `use` / `mod` / `extern crate` | -| Go | `.go` | `import` / import blocks | -| C / C++ | `.c` `.h` `.cpp` `.cc` `.cxx` `.hpp` `.hh` | `#include` (local + system) | -| C# | `.cs` | `using` namespaces | -| Java | `.java` | `import` / `import static` | +Works from small scripts to large monorepos. Parsers are **zero-dep regex** (not cargo / `go.mod` / classpath / `-I`). Depth is two-tier: + +| Depth | Languages | What agents should trust | +|-------|-----------|--------------------------| +| **Deep / ACS** | Python (`.py`); JavaScript / TypeScript (`.js` `.ts` `.jsx` `.tsx` `.mjs` `.cjs` `.mts` `.cts`) | CDIA, BREE barrels, scored resolve, ACS work queue | +| **Regex hint** | Rust (`.rs`); Go (`.go`); C / C++ (`.c` `.h` `.cpp` `.cc` `.cxx` `.hpp` `.hh`); C# (`.cs`); Java (`.java`) | `use` / `import` / `#include` / `using` smokes — not compiler-faithful | Health/journal still work for any monitored path. Parsers are **pragmatic regex** (not full cargo/`go.mod`/classpath/`-I` resolution). On huge monorepos, split scope deliberately: @@ -62,7 +57,7 @@ Always set an explicit root for external trees: `WIKIFIER_PROJECT_ROOT=/abs/path ## Steady state (only touch what needs it) -Full protocol: [`skills/run.md`](skills/run.md) (Agent Protocol v0.6 — package **4.6.x**). +Full protocol: [`skills/run.md`](skills/run.md) (Agent Protocol v0.6.1 — package **4.6.x**). ```bash wikifier session-bootstrap # one-shot: root, health, attention, actions[] @@ -85,7 +80,7 @@ Advanced intel as needed: `get_dependencies`, `get_dependents`, `get_cycles`, ba ## What you get -- **Import analysis** — Python, JS/TS (ESM/CJS, barrels), Rust (`use`/`mod` + best-effort `crate::` paths), Go, C/C++ includes, C# usings; per-edge confidence; barrel expansion for TS/JS +- **Import analysis** — deep/ACS for Python + JS/TS (ESM/CJS, barrels, CDIA); regex-hint maps for Rust/Go/C/C++/C#/Java; per-edge confidence on the deep path - **Incremental pipeline** — pure-Python `update-maps`: dirty parse → import cache → reverse deps → cycles → `library.md` - **Warm agent maps (4.6.3–4.6.7)** — zero-dirty + **index-first** candidates (re-list only when fingerprint / map-scoped index / live count disagree); **MapScope** keeps collect, live count, index filter, and prune aligned; **stdlib SQLite**; content-hash dirty - **Two path lists** — `map_paths.txt` = map package roots; `monitored_paths.txt` = wiki/health watch (**independent** — wiki file lists never collapse the map) diff --git a/file_health.json b/file_health.json index aa847f4..9f5ed49 100644 --- a/file_health.json +++ b/file_health.json @@ -1,16 +1,16 @@ { "version": 2, - "last_updated": "2026-09-04 06:17:32", + "last_updated": "2026-09-11 06:38:37", "entries": { "skills/run.md": { "status": "🟢 Green", - "last_updated": "2026-08-27 11:15:12", - "reason": "4.6.13 plan WP0–WP7 wiki/protocol aligned", - "wiki_content_hash": "sha256:30f6da4a7b46920c1255c339c4c976c43c3323c6a66f03aed9a5e34cca197e04", - "source_content_hash": "sha256:30f6da4a7b46920c1255c339c4c976c43c3323c6a66f03aed9a5e34cca197e04", - "last_meaningful_edit": "2026-08-27 11:14:42", - "last_wiki_refresh": "2026-08-27 11:15:12", - "freshness_provenance": "record-meaningful-edit:2026-08-27 11:14:42 | 4.6.13: close-the-loop mark-green; relative monitors; mark-green:2026-08-27 11:15:12 (wiki hash captured); wiki=run.md" + "last_updated": "2026-09-11 06:37:25", + "reason": "Protocol v0.6.1 notes and language depth table.", + "wiki_content_hash": "sha256:4660244d3ed7b22c8d8bdb3e9473a0cafb0e3bff71b1fde7ef392e49cccc2abc", + "source_content_hash": "sha256:4660244d3ed7b22c8d8bdb3e9473a0cafb0e3bff71b1fde7ef392e49cccc2abc", + "last_meaningful_edit": "2026-09-11 06:37:17", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:17 | Protocol v0.6.1 additive 4.6.x field notes including sqlite-empty vs cache_backend none; language depth table (subid=hon; mark-green:2026-09-11 06:37:25 (wiki hash captured); wiki=run.md" }, "Findings/Milestones-Overview.md": { "status": "🟢 Green", @@ -57,13 +57,13 @@ }, "README.md": { "status": "🟢 Green", - "last_updated": "2026-08-27 11:15:12", - "reason": "4.6.13 plan WP0–WP7 wiki/protocol aligned", - "wiki_content_hash": "sha256:ea07d5a76184443393d655eb09084e42d7f6d521f0168fe8e56f043b441327e9", - "source_content_hash": "sha256:ea07d5a76184443393d655eb09084e42d7f6d521f0168fe8e56f043b441327e9", - "last_meaningful_edit": "2026-08-27 11:14:42", - "last_wiki_refresh": "2026-08-27 11:15:12", - "freshness_provenance": "record-meaningful-edit:2026-08-27 11:14:42 | 4.6.13 test count; mark-green:2026-08-27 11:15:12 (wiki hash captured); wiki=README.md" + "last_updated": "2026-09-11 06:37:25", + "reason": "Deep/ACS vs regex-hint language table.", + "wiki_content_hash": "sha256:10dc0533d5f4db138e593d63173d2d016173976274bf0e47e3ef2d38664d08ff", + "source_content_hash": "sha256:10dc0533d5f4db138e593d63173d2d016173976274bf0e47e3ef2d38664d08ff", + "last_meaningful_edit": "2026-09-11 06:37:17", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:17 | Language table: deep/ACS vs regex hint; protocol v0.6.1 (subid=honest-map).; mark-green:2026-09-11 06:37:25 (wiki hash captured); wiki=README.md" }, "wikifier/mcp/server.py": { "status": "🟢 Green", @@ -134,23 +134,23 @@ }, "CHANGELOG.md": { "status": "🟢 Green", - "last_updated": "2026-08-27 11:15:12", - "reason": "4.6.13 plan WP0–WP7 wiki/protocol aligned", - "wiki_content_hash": "sha256:7a0a54cb4ea5a95815dad3dad5d2e841c74b5b1a47e5cc9b193c96e1a50b7b1c", - "source_content_hash": "sha256:7a0a54cb4ea5a95815dad3dad5d2e841c74b5b1a47e5cc9b193c96e1a50b7b1c", - "last_meaningful_edit": "2026-08-27 11:14:42", - "last_wiki_refresh": "2026-08-27 11:15:12", - "freshness_provenance": "record-meaningful-edit:2026-08-27 11:14:42 | 4.6.13 Keep a Changelog; mark-green:2026-08-27 11:15:12 (wiki hash captured); wiki=CHANGELOG.md" + "last_updated": "2026-09-11 06:37:25", + "reason": "Unreleased honesty notes.", + "wiki_content_hash": "sha256:3a12d8851eaa663ea26b6997143b39b66efb6768dea5965bbae73e104771dbad", + "source_content_hash": "sha256:3a12d8851eaa663ea26b6997143b39b66efb6768dea5965bbae73e104771dbad", + "last_meaningful_edit": "2026-09-11 06:37:17", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:17 | Unreleased: library.md honesty, protocol v0.6.1, language table (subid=honest-map).; mark-green:2026-09-11 06:37:25 (wiki hash captured); wiki=CHANGELOG.md" }, "CLAUDE.md": { "status": "🟢 Green", - "last_updated": "2026-09-04 06:17:32", - "reason": "live hash synced; case-ghost Claude.md pruned", - "wiki_content_hash": "sha256:aa4eed92d69d7575c1d26beb9cc7852d2596cb771d65cea576374fd425856445", - "source_content_hash": "sha256:aa4eed92d69d7575c1d26beb9cc7852d2596cb771d65cea576374fd425856445", - "last_meaningful_edit": "2026-09-04 06:17:31", - "last_wiki_refresh": "2026-09-04 06:17:32", - "freshness_provenance": "record-meaningful-edit:2026-09-04 06:17:31 | re-baseline live hash after Claude.md case-ghost retirement; mark-green:2026-09-04 06:17:32 (wiki hash captured); wiki=CLAUDE.md" + "last_updated": "2026-09-11 06:37:25", + "reason": "Protocol pointer v0.6.1.", + "wiki_content_hash": "sha256:d2a708614ef48b5d1dd0f7bda001f9fff0b65f30f004513200636c00125bcc0d", + "source_content_hash": "sha256:d2a708614ef48b5d1dd0f7bda001f9fff0b65f30f004513200636c00125bcc0d", + "last_meaningful_edit": "2026-09-11 06:37:17", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:17 | Point agent contract at protocol v0.6.1 (subid=honest-map).; mark-green:2026-09-11 06:37:25 (wiki hash captured); wiki=CLAUDE.md" }, "wikifier/__init__.py": { "status": "🟢 Green", @@ -223,11 +223,13 @@ }, "wikifier/library.py": { "status": "🟢 Green", - "last_updated": "2026-08-01 11:25:15", - "reason": "gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure)", - "source_content_hash": "sha256:6312ddc20cd7cd1adef0ec2e5e9818c5030d57ddf1dc49e0384952cf03681ad4", - "last_wiki_refresh": "2026-08-01 11:25:15", - "freshness_provenance": "upsert:🟡 Yellow (non-freshness path); mark-green:2026-08-01 11:25:15 (wiki hash captured)" + "last_updated": "2026-09-11 06:38:32", + "reason": "Wiki captions handle **Role:** as well as ## Purpose.", + "wiki_content_hash": "sha256:89e1fc5b8dbfddb8306f55135392fb5bf5faa5d2e18177285d89f26a649665b8", + "source_content_hash": "sha256:edd02e80508eb135e50681b05307fd2a0e8d269278171f9b2c1d4cf10975a8f6", + "last_meaningful_edit": "2026-09-11 06:38:12", + "last_wiki_refresh": "2026-09-11 06:38:32", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:38:12 | Match **Role:** wiki captions (colon inside bold) so tree lines are not Role:** leftover (subid=honest-map).; mark-green:2026-09-11 06:38:32 (wiki hash captured); wiki=library.py.wiki.md" }, "wikifier/parsers/javascript.py": { "status": "🟢 Green", @@ -291,9 +293,13 @@ }, "library.md": { "status": "🟢 Green", - "last_updated": "2026-06-10 20:20:38 AEST", - "reason": "Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on all 9 projects x 3 modes (exec/static/file): map renders, exec chip + Stop button, no Tailwind, no active errors; 30/30 tests", - "source_content_hash": "sha256:f3f717512ac8c856b79d46d5d47906fdb3f2311025be1bc65186bc3b751bbe2e" + "last_updated": "2026-09-11 06:38:37", + "reason": "Committed map matches live tree after update-maps --full.", + "wiki_content_hash": "sha256:5ced31b3d5598e13d38877627603fcd813d425531c1b3b555c80e1a5211afc03", + "source_content_hash": "sha256:5ced31b3d5598e13d38877627603fcd813d425531c1b3b555c80e1a5211afc03", + "last_meaningful_edit": "2026-09-11 06:38:37", + "last_wiki_refresh": "2026-09-11 06:38:37", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:38:37 | Regenerated from full update-maps on live tree; 4.6.10 leftovers gone (subid=honest-map).; mark-green:2026-09-11 06:38:37 (wiki hash captured); wiki=library.md" }, "screenshot/front_page_review.png": { "status": "🟢 Green", @@ -565,12 +571,12 @@ }, "wikifier/agent_loop.py": { "status": "🟢 Green", - "last_updated": "2026-08-27 11:15:11", - "reason": "4.6.13 plan WP0–WP7 wiki/protocol aligned", - "source_content_hash": "sha256:e08d0f9d3d7ffd57a544277a7ddb7342abd0d216cd4b846f6878b4f1126e7a4a", - "last_meaningful_edit": "2026-08-27 11:14:41", - "last_wiki_refresh": "2026-08-27 11:15:11", - "freshness_provenance": "record-meaningful-edit:2026-08-27 11:14:41 | 4.6.13: emit mark_green action for recorded yellows; mark-green:2026-08-27 11:15:11 (wiki hash captured)" + "last_updated": "2026-09-11 06:37:25", + "reason": "Bootstrap cache_backend refresh; cache_empty / cache_files_indexed additive.", + "source_content_hash": "sha256:feb6a159759552f27af71035557515ca6f367df7e0277df99b769814c27b7893", + "last_meaningful_edit": "2026-09-11 06:37:17", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:17 | Refresh cache_backend after ACS persist; add cache_empty and cache_files_indexed so sqlite-empty is not none (subid=hone; mark-green:2026-09-11 06:37:25 (wiki hash captured)" }, "tests/test_agent_loop.py": { "status": "🟢 Green", @@ -971,6 +977,25 @@ "last_meaningful_edit": "2026-08-27 11:27:44", "last_wiki_refresh": "2026-08-27 11:27:44", "freshness_provenance": "record-meaningful-edit:2026-08-27 11:27:44 | 4.6.13: status tools wrap health/cache in call_with_deadline; mark-green:2026-08-27 11:27:44 (wiki hash captured); wiki=status_ops.py.wiki.md" + }, + "tests/test_library_map_honesty.py": { + "status": "🟢 Green", + "last_updated": "2026-09-11 06:38:32", + "reason": "Caption **Role:** unit test.", + "source_content_hash": "sha256:c9e8e37d44908971ee3167281d1934186d71f8ed97d73ab9019cb1afec616165", + "last_meaningful_edit": "2026-09-11 06:38:32", + "last_wiki_refresh": "2026-09-11 06:38:32", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:38:32 | Cover **Role:** wiki caption parsing (subid=honest-map).; mark-green:2026-09-11 06:38:32 (wiki hash captured)" + }, + "wikifier/library.py.wiki.md": { + "status": "🟢 Green", + "last_updated": "2026-09-11 06:37:25", + "reason": "Generator wiki current.", + "wiki_content_hash": "sha256:89e1fc5b8dbfddb8306f55135392fb5bf5faa5d2e18177285d89f26a649665b8", + "source_content_hash": "sha256:89e1fc5b8dbfddb8306f55135392fb5bf5faa5d2e18177285d89f26a649665b8", + "last_meaningful_edit": "2026-09-11 06:37:18", + "last_wiki_refresh": "2026-09-11 06:37:25", + "freshness_provenance": "record-meaningful-edit:2026-09-11 06:37:18 | Wiki for library.md generator: live-path filter and wiki captions (subid=honest-map).; mark-green:2026-09-11 06:37:25 (wiki hash captured); wiki=library.py.wiki.md" } } } \ No newline at end of file diff --git a/file_health.md b/file_health.md index 8ca2187..2fd1131 100644 --- a/file_health.md +++ b/file_health.md @@ -5,8 +5,8 @@ | .github/ISSUE_TEMPLATE/config.yml | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | .github/workflows/ci.yml | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | .github/workflows/publish.yml | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | -| CHANGELOG.md | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | -| CLAUDE.md | 🟢 Green | 2026-09-04 06:17:32 | live hash synced; case-ghost Claude.md pruned | +| CHANGELOG.md | 🟢 Green | 2026-09-11 06:37:25 | Unreleased honesty notes. | +| CLAUDE.md | 🟢 Green | 2026-09-11 06:37:25 | Protocol pointer v0.6.1. | | CONTRIBUTING.md | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | Findings/2026-06-10-Dogfood-Refactor-Validation.md | 🟢 Green | 2026-06-10 09:54:26 AEST | Self-describing findings doc | | Findings/2026-06-10-Fix-Plan.md | 🟢 Green | 2026-06-10 14:20:33 AEST | Results appended, all phases verified | @@ -39,16 +39,16 @@ | Findings/residual-1-5-closure-2026-07-09.md | 🟢 Green | 2026-07-09 08:07:43 | residual-1-5-closure verified; tests OK (subid=residual-1-5-closure) | | Logged_issues/2026-06-10-brc-scoped-rerun-pathology.md | 🟢 Green | 2026-06-10 19:09:35 AEST | Verified: 30/30 unittest, exports 8/8, churn 4/4; sh update-maps 3m39s->2.0s + hung incremental now 1.5s; Babylon scoped re-run 75min->80.6s, cache 274MB->101MB; all 12 sh commands smoke-tested | | Logged_issues/2026-06-10-js-barrel-churn-selftest-failure.md | 🟢 Green | 2026-06-10 14:19:50 AEST | v4.2.0 fix pass verified: 28/28 unittest, parser self-tests (churn 4/4), llama_index 3837/3837 files 8.5s, Babylon 3905/3905, RecipeLab library.md recovered, redox honest reporting, health CLI flags, MCP smoke. | -| README.md | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | +| README.md | 🟢 Green | 2026-09-11 06:37:25 | Deep/ACS vs regex-hint language table. | | diagnostics.html | 🟢 Green | 2026-06-05 08:33:20 AEST | Wiki summary verified accurate after change. | | file_health.md | 🟢 Green | 2026-06-07 12:47:31 AEST | Phase 1 cruft pruning complete (bulk historical M2-M4/Logged/etc removed per audit). Survivors re-marked Green. subid=simplification-cruft-phase-1. | | index.html | 🟢 Green | 2026-06-11 00:20:17 AEST | Verified: 30/30 tests; tree generated on all 9 projects (llvm 2,940 files renders as clean indented tree); headless 9/9 tree-ok + lazy graph + forced-open render + pan-zoom canvas + file:// banner; parser comment-leak repro now 0 garbage edges | -| library.md | 🟢 Green | 2026-06-10 20:20:38 AEST | Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on all 9 projects x 3 modes (exec/static/file): map renders, exec chip + Stop button, no Tailwind, no active errors; 30/30 tests | +| library.md | 🟢 Green | 2026-09-11 06:38:37 | Committed map matches live tree after update-maps --full. | | map_paths.txt | 🟢 Green | 2026-07-12 13:26:29 | 4.6.6 verified | | monitored_paths.txt | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | pyproject.toml | 🟢 Green | 2026-06-10 14:41:19 AEST | Build + twine check pass; clean-room wheel install verified | | screenshot/front_page_review.png | 🟢 Green | 2026-06-11 00:37:47 AEST | Asset referenced by README | -| skills/run.md | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | +| skills/run.md | 🟢 Green | 2026-09-11 06:37:25 | Protocol v0.6.1 notes and language depth table. | | tests/ | 🟢 Green | 2026-06-10 16:59:05 AEST | Verified: 30/30 unittest, exports 8/8, churn 4/4; Babylon full run 25m52s->5m52s and 417k->44k edges; worst file 990->55; RecipeLab identical 671 edges; e2e cache carries imported_names + barrel_leaf_selection | | tests/__init__.py | 🟢 Green | 2026-07-09 06:34:55 | hygiene session complete 4.5.6; 53 tests OK | | tests/_base.py | 🟢 Green | 2026-07-09 06:34:55 | hygiene session complete 4.5.6; 53 tests OK | @@ -69,6 +69,7 @@ | tests/test_health.py | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | tests/test_import_cache.py | 🟢 Green | 2026-08-13 17:08:27 | Persist-path reverse increment test green. | | tests/test_index_map_paths.py | 🟢 Green | 2026-07-12 13:41:02 | 125 unittest OK | +| tests/test_library_map_honesty.py | 🟢 Green | 2026-09-11 06:38:32 | Caption **Role:** unit test. | | tests/test_multi_lang_parsers.py | 🟢 Green | 2026-07-09 06:34:55 | hygiene session complete 4.5.6; 53 tests OK | | tests/test_parsers.py | 🟢 Green | 2026-07-09 06:34:55 | hygiene session complete 4.5.6; 53 tests OK | | tests/test_plan_2026_08_27.py | 🟢 Green | 2026-08-27 11:27:44 | deadline tests wiki | @@ -79,7 +80,7 @@ | wikifier.sh | 🟢 Green | 2026-08-01 11:25:19 | gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) | | wikifier/__init__.py | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | wikifier/__main__.py | 🟢 Green | 2026-07-09 06:34:55 | hygiene session complete 4.5.6; 53 tests OK | -| wikifier/agent_loop.py | 🟢 Green | 2026-08-27 11:15:11 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | +| wikifier/agent_loop.py | 🟢 Green | 2026-09-11 06:37:25 | Bootstrap cache_backend refresh; cache_empty / cache_files_indexed additive. | | wikifier/api.py | 🟢 Green | 2026-08-27 11:15:11 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | wikifier/cache/__init__.py | 🟢 Green | 2026-08-13 16:51:15 | Named cache package exports real io/files/graph/cycles/acs/barrel. | | wikifier/cache/_core.py | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | @@ -95,7 +96,8 @@ | wikifier/health_pkg/__init__.py | 🟢 Green | 2026-08-27 11:15:12 | 4.6.13 plan WP0–WP7 wiki/protocol aligned | | wikifier/import_cache.py | 🟢 Green | 2026-09-04 06:16:42 | wiki + baseline after shim confirmation; tests OK | | wikifier/index.html | 🟢 Green | 2026-06-11 00:20:18 AEST | Verified: 30/30 tests; tree generated on all 9 projects (llvm 2,940 files renders as clean indented tree); headless 9/9 tree-ok + lazy graph + forced-open render + pan-zoom canvas + file:// banner; parser comment-leak repro now 0 garbage edges | -| wikifier/library.py | 🟢 Green | 2026-08-01 11:25:15 | gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) | +| wikifier/library.py | 🟢 Green | 2026-09-11 06:38:32 | Wiki captions handle **Role:** as well as ## Purpose. | +| wikifier/library.py.wiki.md | 🟢 Green | 2026-09-11 06:37:25 | Generator wiki current. | | wikifier/locking.py | 🟢 Green | 2026-08-01 11:25:14 | gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) | | wikifier/mcp/README.md | 🟢 Green | 2026-07-09 08:51:23 | 4.6.2 polish+dogfood verified 74 tests (subid=agent-ideal-loop-polish) | | wikifier/mcp/__init__.py | 🟢 Green | 2026-06-10 09:27:38 AEST | Refactor verified: py_compile + no-mcp/no-fcntl import sims + parser self-tests + check-changes/update-maps/health smoke all pass. Interface unchanged. | diff --git a/journal/2026/09/11.md b/journal/2026/09/11.md new file mode 100644 index 0000000..c4a092c --- /dev/null +++ b/journal/2026/09/11.md @@ -0,0 +1,44 @@ +## [2026-09-11 06:37:17] record-change +**File:** wikifier/library.py +**Reason:** Omit missing-on-disk cache keys from library.md; wiki captions not health audit reasons (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** wikifier/agent_loop.py +**Reason:** Refresh cache_backend after ACS persist; add cache_empty and cache_files_indexed so sqlite-empty is not none (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** tests/test_library_map_honesty.py +**Reason:** Test library.md names only live files; generator drops ghosts; bootstrap sqlite-empty vs none (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** skills/run.md +**Reason:** Protocol v0.6.1 additive 4.6.x field notes including sqlite-empty vs cache_backend none; language depth table (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** README.md +**Reason:** Language table: deep/ACS vs regex hint; protocol v0.6.1 (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** CHANGELOG.md +**Reason:** Unreleased: library.md honesty, protocol v0.6.1, language table (subid=honest-map). + +## [2026-09-11 06:37:17] record-change +**File:** CLAUDE.md +**Reason:** Point agent contract at protocol v0.6.1 (subid=honest-map). + +## [2026-09-11 06:37:18] record-change +**File:** wikifier/library.py.wiki.md +**Reason:** Wiki for library.md generator: live-path filter and wiki captions (subid=honest-map). + +## [2026-09-11 06:38:12] record-change +**File:** wikifier/library.py +**Reason:** Match **Role:** wiki captions (colon inside bold) so tree lines are not Role:** leftover (subid=honest-map). + +## [2026-09-11 06:38:32] record-change +**File:** tests/test_library_map_honesty.py +**Reason:** Cover **Role:** wiki caption parsing (subid=honest-map). + +## [2026-09-11 06:38:37] record-change +**File:** library.md +**Reason:** Regenerated from full update-maps on live tree; 4.6.10 leftovers gone (subid=honest-map). + diff --git a/library.md b/library.md index 1cb5d4c..b85099f 100644 --- a/library.md +++ b/library.md @@ -5,173 +5,164 @@ ## File Tree -> Every parsed/tracked file, organised by folder. Descriptions come from -> the agent wiki (file_health). The dependency graph is further below. +> Every parsed/tracked file, organised by folder. Captions come from +> `*.wiki.md` purpose/role text when present. Health *reasons* are audit +> stamps and are not copied here. The dependency graph is further below. ```text -Wikifier/ (133 files) +workspace/ (129 files) ├── .github/ +│ ├── ISSUE_TEMPLATE/ +│ │ └── config.yml │ └── workflows/ -│ └── publish.yml — Verified: bash -n, dynamic banner shows v4.2.0 from package, YAML parses, 28/28 tests, pac… +│ ├── ci.yml +│ └── publish.yml ├── Findings/ -│ ├── 2026-06-10-Dogfood-Refactor-Validation.md — Self-describing findings doc -│ ├── 2026-06-10-Fix-Plan.md — Results appended, all phases verified -│ ├── 2026-08-13-implementation-plan.md — implementation plan -│ ├── 2026-08-13-research-01-parsers.md — Research findings saved. -│ ├── 2026-08-13-research-02-cache-graph.md — Research findings saved. -│ ├── 2026-08-13-research-03-health-protocol.md — Research findings saved. -│ ├── 2026-08-13-research-04-mcp-cli.md — Research findings saved. -│ ├── 2026-08-13-research-05-packaging-tests.md — Research findings saved. -│ ├── 2026-08-27-plan.md — 2026-08-27-plan: proposed 4.6.13 follow-up from five-slice research; not executed -│ ├── M5-Dogfood-Assessment-Report.md — kept; stale yellow cleared -│ ├── M5-Dogfood-Progress.md — kept; stale yellow cleared -│ ├── M5.1-cross-hardening-analysis.md — kept; stale yellow cleared -│ ├── Milestones-Overview.md — kept; stale yellow cleared -│ ├── agent-first-ideal-loop-2026-07-09.md — 4.6.1 content-honest legacy fix verified (subid=agent-ideal-loop) -│ ├── agent-ideal-loop-polish-dogfood-2026-07-09.md — 4.6.2 polish+dogfood verified 74 tests (subid=agent-ideal-loop-polish) -│ ├── agent-scale-perf-accuracy-2026-07-12.md — findings recorded -│ ├── agent-scale-sqlite-coverage-2026-07-12.md — 4.6.4 sqlite coverage verified 93 tests -│ ├── agent-walk-coverage-cache-2026-07-12.md — findings updated -│ ├── dogfood-goal-pass1-2026-07-09.json — goal verification complete -│ ├── dogfood-goal-pass2-2026-07-09.json — goal verification complete -│ ├── dogfood-hygiene-fix-2026-07-09.json — verified 53 tests; dogfood validate 0/8 -│ ├── dogfood-hygiene-fix-2026-07-09.md — verified 53 tests; dogfood validate 0/8 -│ ├── gap-amendment-closure-2026-08-01.md — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -│ ├── gap-amendment-plan-2026-08-01.md — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -│ ├── gap-closure-report.md — G12 closed; 39/39 tests -│ ├── index-first-map-paths-2026-07-12.md — evidence updated -│ ├── long-horizon-autonomous-ops.md — goal verification complete -│ ├── p6_real_world_validation_report.md — kept; stale yellow cleared -│ └── residual-1-5-closure-2026-07-09.md — residual-1-5-closure verified; tests OK (subid=residual-1-5-closure) +│ ├── 2026-06-10-Dogfood-Refactor-Validation.md +│ ├── 2026-06-10-Fix-Plan.md +│ ├── 2026-08-13-implementation-plan.md +│ ├── 2026-08-13-research-01-parsers.md +│ ├── 2026-08-13-research-02-cache-graph.md +│ ├── 2026-08-13-research-03-health-protocol.md +│ ├── 2026-08-13-research-04-mcp-cli.md +│ ├── 2026-08-13-research-05-packaging-tests.md +│ ├── 2026-08-27-plan.md +│ ├── M5-Dogfood-Assessment-Report.md +│ ├── M5-Dogfood-Progress.md +│ ├── M5.1-cross-hardening-analysis.md +│ ├── Milestones-Overview.md +│ ├── agent-first-ideal-loop-2026-07-09.md +│ ├── agent-ideal-loop-polish-dogfood-2026-07-09.md +│ ├── agent-scale-perf-accuracy-2026-07-12.md +│ ├── agent-scale-sqlite-coverage-2026-07-12.md +│ ├── agent-walk-coverage-cache-2026-07-12.md +│ ├── dogfood-goal-pass1-2026-07-09.json +│ ├── dogfood-goal-pass2-2026-07-09.json +│ ├── dogfood-hygiene-fix-2026-07-09.json +│ ├── dogfood-hygiene-fix-2026-07-09.md +│ ├── gap-amendment-closure-2026-08-01.md +│ ├── gap-amendment-plan-2026-08-01.md +│ ├── gap-closure-report.md +│ ├── index-first-map-paths-2026-07-12.md +│ ├── long-horizon-autonomous-ops.md +│ ├── p6_real_world_validation_report.md +│ └── residual-1-5-closure-2026-07-09.md ├── Logged_issues/ -│ ├── 2026-06-10-brc-scoped-rerun-pathology.md — Verified: 30/30 unittest, exports 8/8, churn 4/4; sh update-maps 3m39s->2.0s + hung increm… -│ └── 2026-06-10-js-barrel-churn-selftest-failure.md — v4.2.0 fix pass verified: 28/28 unittest, parser self-tests (churn 4/4), llama_index 3837/… +│ ├── 2026-06-10-brc-scoped-rerun-pathology.md +│ └── 2026-06-10-js-barrel-churn-selftest-failure.md ├── screenshot/ -│ └── front_page_review.png — Asset referenced by README +│ └── front_page_review.png ├── skills/ -│ └── run.md — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) +│ └── run.md ├── tests/ │ ├── selftest/ -│ │ ├── __init__.py — hygiene session complete 4.5.6; 53 tests OK -│ │ ├── run_cdia_selftest.py — hygiene session complete 4.5.6; 53 tests OK -│ │ ├── run_contracts_selftest.py — hygiene session complete 4.5.6; 53 tests OK -│ │ ├── run_javascript_selftest.py — hygiene session complete 4.5.6; 53 tests OK -│ │ ├── run_python_parser_selftest.py — hygiene session complete 4.5.6; 53 tests OK -│ │ └── run_resolution_selftest.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── __init__.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── _base.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── run_all.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── test_agent_loop.py — 4.6.2 polish+dogfood verified 74 tests (subid=agent-ideal-loop-polish) -│ ├── test_agent_scale.py — ACS persist regression green -│ ├── test_agent_surface_contracts.py — PEP585 future-import scan covers javascript.py. -│ ├── test_barrel_invalidation.py — unskipped content-honest barrel tests -│ ├── test_cache_store.py — instrumented warm load assertion -│ ├── test_gap_amendment_2026_08.py — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -│ ├── test_gap_closure.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── test_health.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── test_import_cache.py — Persist-path reverse increment test green. -│ ├── test_index_map_paths.py — 125 unittest OK +│ │ ├── __init__.py +│ │ ├── run_cdia_selftest.py +│ │ ├── run_contracts_selftest.py +│ │ ├── run_javascript_selftest.py +│ │ ├── run_python_parser_selftest.py +│ │ └── run_resolution_selftest.py +│ ├── __init__.py +│ ├── _base.py +│ ├── run_all.py +│ ├── test_agent_loop.py +│ ├── test_agent_scale.py +│ ├── test_agent_surface_contracts.py +│ ├── test_barrel_invalidation.py +│ ├── test_cache_store.py +│ ├── test_gap_amendment_2026_08.py +│ ├── test_gap_closure.py — Gap-closure regressions — G4 ACS actionable low-conf, G5 health module vs `wikifier.health… +│ ├── test_health.py +│ ├── test_import_cache.py +│ ├── test_index_map_paths.py │ ├── test_init_seed.py -│ ├── test_multi_lang_parsers.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── test_parsers.py — hygiene session complete 4.5.6; 53 tests OK +│ ├── test_library_map_honesty.py +│ ├── test_multi_lang_parsers.py +│ ├── test_parsers.py │ ├── test_plan_2026_08_27.py -│ ├── test_selftest_wrappers.py — G12 closed; 39/39 tests -│ └── test_walk_coverage_resolvers.py — poison test green -├── wikifier/ (60 files) +│ ├── test_selftest_wrappers.py +│ └── test_walk_coverage_resolvers.py +├── wikifier/ (53 files) │ ├── cache/ -│ │ ├── __init__.py — Named cache package exports real io/files/graph/cycles/acs/barrel. -│ │ ├── _core.py — content changed since last trusted baseline (check_changes content-honest) +│ │ ├── __init__.py +│ │ ├── _core.py │ │ ├── acs.py │ │ ├── barrel.py │ │ ├── cycles.py │ │ ├── diagnostics.py -│ │ ├── files.py — Real file ops + same-second dirty +│ │ ├── files.py — File entries, `sha256:` content hash, `compute_files_needing_reparse` (light index; same-s… │ │ ├── graph.py -│ │ ├── io.py — Real cache I/O +│ │ ├── io.py — SQLite-primary `load_cache` / `save_cache` / `load_mtime_index`. Legacy JSON dual-read onl… │ │ └── streaming.py │ ├── health_pkg/ -│ │ └── __init__.py — content changed since last trusted baseline (check_changes content-honest) +│ │ └── __init__.py │ ├── mcp/ │ │ ├── tools/ -│ │ │ ├── __init__.py — content changed since last trusted baseline (check_changes content-honest) -│ │ │ ├── _common.py — Slim helpers; no second FastMCP. -│ │ │ ├── intel.py — DELETED — path missing on disk (check_changes ghost detection) -│ │ │ ├── status.py — DELETED — path missing on disk (check_changes ghost detection) -│ │ │ └── workflow.py — DELETED — path missing on disk (check_changes ghost detection) -│ │ ├── README.md — 4.6.2 polish+dogfood verified 74 tests (subid=agent-ideal-loop-polish) -│ │ ├── __init__.py — Refactor verified: py_compile + no-mcp/no-fcntl import sims + parser self-tests + check-ch… -│ │ ├── deadline.py -│ │ ├── server.py — wikifier-mcp main restored via server_impl -│ │ ├── server_backup.py -│ │ └── server_impl.py — content change or no baseline (check_changes content-honest auto-detect) +│ │ │ ├── __init__.py +│ │ │ └── _common.py +│ │ ├── README.md +│ │ ├── __init__.py +│ │ ├── deadline.py — Stdlib in-process wall-clock cap for MCP tools (`call_with_deadline`, `MCP_INPROCESS_DEADL… +│ │ ├── server.py — Installed MCP entry (`wikifier-mcp`, `python -m wikifier.mcp.server`). Re-exports `mcp` + … +│ │ ├── server_impl.py +│ │ └── status_ops.py — Library health/cache work for MCP get_project_status and get_files_needing_attention, wrap… │ ├── parsers/ │ │ ├── bree/ -│ │ │ ├── __init__.py — content change or no baseline (check_changes content-honest auto-detect) -│ │ │ └── _bree.py -│ │ ├── javascript/ │ │ │ ├── __init__.py -│ │ │ └── _parser.py -│ │ ├── __init__.py — lazy language imports -│ │ ├── _edge.py — content changed since last trusted baseline (check_changes content-honest) -│ │ ├── _ldsi.py -│ │ ├── bree.py -│ │ ├── c_cpp.py — content changed since last trusted baseline (check_changes content-honest) -│ │ ├── cdia.py — mtime-only / post-4.5.x auto-yellow cleared; git content clean at mark-green (hygiene sess… -│ │ ├── csharp.py — 4.6.5 verified -│ │ ├── go_lang.py — 4.6.4 sqlite coverage verified 93 tests -│ │ ├── java.py — hygiene session complete 4.5.6; 53 tests OK -│ │ ├── javascript.py — content changed since last trusted baseline (check_changes content-honest) -│ │ ├── python.py — content changed since last trusted baseline (check_changes content-honest) -│ │ └── rust.py — crate resolve unit tested +│ │ │ └── _bree.py +│ │ ├── __init__.py +│ │ ├── _edge.py +│ │ ├── _ldsi.py — Shared LDSI helpers (`_extract_balanced_argument`, `_extract_candidate_literals`, `_analyz… +│ │ ├── c_cpp.py — Zero-dep C/C++ `#include` parser. `parse_c_cpp_imports(filepath)` → edge list for `.c/.h/.… +│ │ ├── cdia.py +│ │ ├── csharp.py +│ │ ├── go_lang.py +│ │ ├── java.py +│ │ ├── javascript.py — : JavaScript / TypeScript import parser for Milestone 2 (Dependency Intelligence). +│ │ ├── python.py — : Core Python import parser for Milestone 2 (Dependency Intelligence). +│ │ └── rust.py │ ├── scripts/ -│ │ ├── wikifier.ps1 — Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on… -│ │ └── wikifier.sh — synced with root; portable rel paths (subid=post-assess-hygiene) -│ ├── __init__.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── __main__.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── agent_loop.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── api.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── cache_store.py — Incremental sqlite upsert -│ ├── candidates.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── cli.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── contracts.py — reserved keys _candidate_list/_map_coverage/_reverse_signature -│ ├── daemon.py — mtime-only auto-yellow cleared (session tour check-changes); no content edit this session;… -│ ├── diagnostics.py — hygiene session complete 4.5.6; 53 tests OK -│ ├── health.py -│ ├── health_impl.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── import_cache.py — content changed since last trusted baseline (check_changes content-honest) -│ ├── import_cache_impl.py -│ ├── index.html — Verified: 30/30 tests; tree generated on all 9 projects (llvm 2,940 files renders as clean… -│ ├── library.py — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -│ ├── locking.py — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -│ ├── project_root.py — residual-1-5-closure verified; tests OK (subid=residual-1-5-closure) -│ ├── resolution.py — mtime-only / post-4.5.x auto-yellow cleared; git content clean at mark-green (hygiene sess… -│ └── serve.py — Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on… -├── CHANGELOG.md — 4.6.10 notes -├── CLAUDE.md — test count synced to 49 -├── Claude.md — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) -├── README.md — 4.6.6 verified -├── diagnostics.html — Wiki summary verified accurate after change. -├── file_health.md — Phase 1 cruft pruning complete (bulk historical M2-M4/Logged/etc removed per audit). Survi… -├── index.html — Verified: 30/30 tests; tree generated on all 9 projects (llvm 2,940 files renders as clean… -├── library.md — Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on… -├── map_paths.txt — 4.6.6 verified -├── monitored_paths.txt — 4.6.6 verified -├── pyproject.toml — Build + twine check pass; clean-room wheel install verified -├── wikifier.bat — Verified: bash -n, dynamic banner shows v4.2.0 from package, YAML parses, 28/28 tests, pac… -├── wikifier.ps1 — Verified: endpoint whitelist + Origin/Host 403s + clean shutdown via curl; headless DOM on… -└── wikifier.sh — gap amendment 4.6.9 closed-when verified (subid=gap-amendment-closure) +│ │ ├── wikifier.ps1 +│ │ └── wikifier.sh +│ ├── __init__.py +│ ├── __main__.py +│ ├── agent_loop.py +│ ├── api.py +│ ├── cache_store.py +│ ├── candidates.py +│ ├── cli.py — Hybrid agent CLI. Re-exports `wikifier.api` so `from wikifier.cli import check_changes` wo… +│ ├── contracts.py +│ ├── daemon.py +│ ├── diagnostics.py +│ ├── health_impl.py +│ ├── import_cache.py — Backward-compat shim. Real implementation lives in `wikifier.cache` (`from .cache import *… +│ ├── index.html +│ ├── library.py — : Pure-Python generator for committed `library.md` (file tree, Mermaid, tables, ACS, rever… +│ ├── library.py.wiki.md +│ ├── locking.py +│ ├── project_root.py +│ ├── resolution.py +│ └── serve.py +├── CHANGELOG.md +├── CLAUDE.md +├── CONTRIBUTING.md +├── README.md +├── diagnostics.html +├── file_health.md +├── index.html +├── library.md +├── map_paths.txt +├── monitored_paths.txt +├── pyproject.toml +├── wikifier.bat +├── wikifier.ps1 +└── wikifier.sh ``` ## Dependency Graph (Mermaid) ```mermaid graph TD - subgraph root - wikifier["wikifier"] - wikifier_parsers["wikifier.parsers"] - wikifier_parsers_project_root["wikifier.parsers.project_root"] - wikifier_parsers_resolution["wikifier.parsers.resolution"] - end subgraph tests tests__base_py["_base.py"] tests_run_all_py["run_all.py"] @@ -191,6 +182,7 @@ graph TD tests_test_import_cache_py["test_import_cache.py"] tests_test_index_map_paths_py["test_index_map_paths.py"] tests_test_init_seed_py["test_init_seed.py"] + tests_test_library_map_honesty_py["test_library_map_honesty.py"] tests_test_multi_lang_parsers_py["test_multi_lang_parsers.py"] tests_test_parsers_py["test_parsers.py"] tests_test_plan_2026_08_27_py["test_plan_2026_08_27.py"] @@ -220,7 +212,6 @@ graph TD wikifier_diagnostics_py["diagnostics.py"] wikifier_health_impl_py["health_impl.py"] wikifier_health_pkg___init___py["__init__.py"] - wikifier_health_py["health.py"] wikifier_import_cache_py["import_cache.py"] wikifier_library_py["library.py"] wikifier_locking_py["locking.py"] @@ -228,10 +219,8 @@ graph TD wikifier_mcp_deadline_py["deadline.py"] wikifier_mcp_server_impl_py["server_impl.py"] wikifier_mcp_server_py["server.py"] + wikifier_mcp_status_ops_py["status_ops.py"] wikifier_mcp_tools__common_py["_common.py"] - wikifier_mcp_tools_intel_py["intel.py"] - wikifier_mcp_tools_status_py["status.py"] - wikifier_mcp_tools_workflow_py["workflow.py"] wikifier_parsers___init___py["__init__.py"] wikifier_parsers__edge_py["_edge.py"] wikifier_parsers__ldsi_py["_ldsi.py"] @@ -252,6 +241,8 @@ graph TD subgraph External _["."] __[".."] + __project_root["..project_root"] + __resolution["..resolution"] _wikifier_health_["'wikifier.health'"] _wikifier_import_cache_impl_["'wikifier.import_cache_impl'"] _wikifier_mcp_server_["'wikifier.mcp.server'"] @@ -299,6 +290,7 @@ graph TD typing["typing"] unittest["unittest"] warnings["warnings"] + wikifier["wikifier"] wikifier_agent_loop["wikifier.agent_loop"] wikifier_api["wikifier.api"] wikifier_cache["wikifier.cache"] @@ -312,7 +304,8 @@ graph TD wikifier_import_cache["wikifier.import_cache"] wikifier_library["wikifier.library"] wikifier_mcp_deadline["wikifier.mcp.deadline"] - wikifier_mcp_server_impl["wikifier.mcp.server_impl"] + wikifier_mcp_status_ops["wikifier.mcp.status_ops"] + wikifier_parsers["wikifier.parsers"] wikifier_parsers_bree["wikifier.parsers.bree"] wikifier_parsers_cdia["wikifier.parsers.cdia"] wikifier_parsers_javascript["wikifier.parsers.javascript"] @@ -320,13 +313,6 @@ graph TD wikifier_project_root["wikifier.project_root"] wikifier_resolution["wikifier.resolution"] end - wikifier_mcp_server_py --> wikifier_mcp_server_impl_py - wikifier_candidates_py -.-> fnmatch - wikifier_candidates_py -.-> os - wikifier_candidates_py -.-> subprocess - wikifier_candidates_py -.-> dataclasses - wikifier_candidates_py -.-> pathlib - wikifier_candidates_py -.-> typing wikifier___init___py -.-> sys wikifier___init___py -.-> _ wikifier___init___py --> wikifier_cli_py @@ -339,12 +325,79 @@ graph TD wikifier_agent_loop_py --> wikifier_project_root_py wikifier_agent_loop_py -.-> _ wikifier_agent_loop_py -. ? .-> _wikifier_health_ + wikifier_api_py -.-> os + wikifier_api_py -.-> sys + wikifier_api_py -.-> platform + wikifier_api_py -.-> subprocess + wikifier_api_py -.-> shutil + wikifier_api_py -.-> pathlib + wikifier_api_py -.-> typing + wikifier_api_py -.-> contextlib + wikifier_api_py --> wikifier_project_root_py + wikifier_api_py --> wikifier_candidates_py + wikifier_api_py --> wikifier_contracts_py + wikifier_api_py -.-> datetime + wikifier_api_py -.-> _ + wikifier_api_py --> wikifier_library_py + wikifier_api_py --> wikifier_parsers___init___py + wikifier_api_py --> wikifier_resolution_py + wikifier_api_py --> wikifier_agent_loop_py + wikifier_api_py -.-> importlib_resources + wikifier_cache___init___py --> wikifier_cache_io_py + wikifier_cache___init___py --> wikifier_cache_files_py + wikifier_cache___init___py --> wikifier_cache_graph_py + wikifier_cache___init___py --> wikifier_cache_cycles_py + wikifier_cache___init___py --> wikifier_cache_acs_py + wikifier_cache___init___py --> wikifier_cache_barrel_py + wikifier_cache___init___py --> wikifier_cache_diagnostics_py + wikifier_cache___init___py --> wikifier_cache_streaming_py + wikifier_cache___init___py --> wikifier_contracts_py + wikifier_cache__core_py -.-> json + wikifier_cache__core_py -.-> os + wikifier_cache__core_py -.-> time + wikifier_cache__core_py -.-> hashlib + wikifier_cache__core_py -.-> pathlib + wikifier_cache__core_py -.-> typing + wikifier_cache__core_py -.-> collections + wikifier_cache__core_py -.-> datetime + wikifier_cache__core_py -.-> __ + wikifier_cache__core_py --> wikifier_contracts_py + wikifier_cache__core_py --> wikifier_resolution_py + wikifier_cache__core_py --> wikifier_cache_io_py + wikifier_cache__core_py --> wikifier_cache_files_py + wikifier_cache__core_py --> wikifier_parsers_bree___init___py + wikifier_cache__core_py -.-> dataclasses + wikifier_cache__core_py --> wikifier_project_root_py + wikifier_cache__core_py --> wikifier_parsers___init___py + wikifier_cache_acs_py --> wikifier_cache__core_py + wikifier_cache_barrel_py --> wikifier_cache__core_py + wikifier_cache_cycles_py --> wikifier_cache__core_py + wikifier_cache_diagnostics_py --> wikifier_cache__core_py + wikifier_cache_files_py -.-> hashlib + wikifier_cache_files_py -.-> pathlib + wikifier_cache_files_py -.-> typing + wikifier_cache_files_py --> wikifier_cache_io_py + wikifier_cache_graph_py --> wikifier_cache__core_py + wikifier_cache_io_py -.-> json + wikifier_cache_io_py -.-> os + wikifier_cache_io_py -.-> sys + wikifier_cache_io_py -.-> traceback + wikifier_cache_io_py -.-> pathlib + wikifier_cache_io_py -.-> typing + wikifier_cache_io_py -.-> __ + wikifier_cache_streaming_py --> wikifier_cache__core_py wikifier_cache_store_py -.-> json wikifier_cache_store_py -.-> os wikifier_cache_store_py -.-> sqlite3 wikifier_cache_store_py -.-> contextlib wikifier_cache_store_py -.-> pathlib wikifier_cache_store_py -.-> typing + wikifier_candidates_py -.-> fnmatch + wikifier_candidates_py -.-> os + wikifier_candidates_py -.-> subprocess + wikifier_candidates_py -.-> dataclasses + wikifier_candidates_py -.-> pathlib + wikifier_candidates_py -.-> typing wikifier_cli_py -.-> json wikifier_cli_py -.-> os wikifier_cli_py -.-> platform @@ -374,21 +427,22 @@ graph TD wikifier_daemon_py -.-> pathlib wikifier_daemon_py -.-> typing wikifier_daemon_py --> wikifier_cli_py - wikifier_daemon_py -.-> wikifier + wikifier_daemon_py -.-> _ wikifier_diagnostics_py -.-> json wikifier_diagnostics_py -.-> dataclasses wikifier_diagnostics_py -.-> enum wikifier_diagnostics_py -.-> typing - wikifier_health_py -.-> hashlib - wikifier_health_py -.-> json - wikifier_health_py -.-> os - wikifier_health_py -.-> re - wikifier_health_py -.-> sys - wikifier_health_py -.-> dataclasses - wikifier_health_py -.-> datetime - wikifier_health_py -.-> pathlib - wikifier_health_py -.-> typing - wikifier_health_py -.-> wikifier + wikifier_health_impl_py -.-> hashlib + wikifier_health_impl_py -.-> json + wikifier_health_impl_py -.-> os + wikifier_health_impl_py -.-> re + wikifier_health_impl_py -.-> sys + wikifier_health_impl_py -.-> dataclasses + wikifier_health_impl_py -.-> datetime + wikifier_health_impl_py -.-> pathlib + wikifier_health_impl_py -.-> typing + wikifier_health_impl_py -.-> _ + wikifier_health_pkg___init___py --> wikifier_health_impl_py wikifier_import_cache_py --> wikifier_cache___init___py wikifier_library_py -.-> json wikifier_library_py -.-> os @@ -406,11 +460,58 @@ graph TD wikifier_locking_py -.-> pathlib wikifier_locking_py -.-> typing wikifier_mcp___init___py --> wikifier_mcp_server_py + wikifier_mcp_deadline_py -.-> os + wikifier_mcp_deadline_py -.-> threading + wikifier_mcp_deadline_py -.-> typing + wikifier_mcp_server_py --> wikifier_mcp_server_impl_py + wikifier_mcp_server_impl_py -.-> subprocess + wikifier_mcp_server_impl_py -.-> re + wikifier_mcp_server_impl_py -.-> os + wikifier_mcp_server_impl_py -.-> sys + wikifier_mcp_server_impl_py -.-> json + wikifier_mcp_server_impl_py -.-> wikifier_import_cache + wikifier_mcp_server_impl_py -.-> time + wikifier_mcp_server_impl_py -.-> importlib + wikifier_mcp_server_impl_py -.-> argparse + wikifier_mcp_server_impl_py -.-> mcp_server_fastmcp + wikifier_mcp_server_impl_py -.-> pydantic + wikifier_mcp_server_impl_py -.-> pathlib + wikifier_mcp_server_impl_py -.-> typing + wikifier_mcp_server_impl_py -.-> datetime + wikifier_mcp_server_impl_py --> wikifier_mcp_deadline_py + wikifier_mcp_server_impl_py --> wikifier_mcp_status_ops_py + wikifier_mcp_server_impl_py -.-> wikifier_cli + wikifier_mcp_server_impl_py -. ? .-> _wikifier_health_ + wikifier_mcp_status_ops_py -.-> importlib + wikifier_mcp_status_ops_py -.-> wikifier_import_cache + wikifier_mcp_status_ops_py -.-> pathlib + wikifier_mcp_status_ops_py -.-> typing + wikifier_mcp_status_ops_py --> wikifier_mcp_deadline_py + wikifier_mcp_status_ops_py -. ? .-> _wikifier_health_ + wikifier_mcp_tools__common_py -.-> pathlib + wikifier_mcp_tools__common_py -.-> typing + wikifier_mcp_tools__common_py -.-> wikifier_api wikifier_parsers___init___py -.-> typing wikifier_parsers___init___py -.-> importlib wikifier_parsers___init___py -. ? .-> modname____name__ wikifier_parsers__edge_py -.-> typing wikifier_parsers__edge_py --> wikifier_contracts_py + wikifier_parsers__ldsi_py -.-> re + wikifier_parsers__ldsi_py -.-> typing + wikifier_parsers_bree___init___py --> wikifier_parsers_bree__bree_py + wikifier_parsers_bree__bree_py -.-> json + wikifier_parsers_bree__bree_py -.-> re + wikifier_parsers_bree__bree_py -.-> warnings + wikifier_parsers_bree__bree_py -.-> hashlib + wikifier_parsers_bree__bree_py -.-> os + wikifier_parsers_bree__bree_py -.-> time + wikifier_parsers_bree__bree_py -.-> dataclasses + wikifier_parsers_bree__bree_py -.-> pathlib + wikifier_parsers_bree__bree_py -.-> typing + wikifier_parsers_bree__bree_py -.-> __project_root + wikifier_parsers_bree__bree_py -.-> __resolution + wikifier_parsers_bree__bree_py -.-> wikifier_resolution + wikifier_parsers_bree__bree_py -.-> __ wikifier_parsers_c_cpp_py -.-> re wikifier_parsers_c_cpp_py -.-> pathlib wikifier_parsers_c_cpp_py -.-> typing @@ -489,146 +590,15 @@ graph TD wikifier_serve_py -.-> http_server wikifier_serve_py -.-> pathlib wikifier_serve_py --> wikifier_cli_py - wikifier_serve_py -.-> wikifier - wikifier_api_py -.-> os - wikifier_api_py -.-> sys - wikifier_api_py -.-> platform - wikifier_api_py -.-> subprocess - wikifier_api_py -.-> shutil - wikifier_api_py -.-> pathlib - wikifier_api_py -.-> typing - wikifier_api_py -.-> contextlib - wikifier_api_py --> wikifier_project_root_py - wikifier_api_py --> wikifier_candidates_py - wikifier_api_py --> wikifier_contracts_py - wikifier_api_py -.-> datetime - wikifier_api_py -.-> _ - wikifier_api_py --> wikifier_library_py - wikifier_api_py --> wikifier_parsers___init___py - wikifier_api_py --> wikifier_resolution_py - wikifier_api_py --> wikifier_agent_loop_py - wikifier_api_py -.-> importlib_resources - wikifier_cache___init___py --> wikifier_cache_io_py - wikifier_cache___init___py --> wikifier_cache_files_py - wikifier_cache___init___py --> wikifier_cache_graph_py - wikifier_cache___init___py --> wikifier_cache_cycles_py - wikifier_cache___init___py --> wikifier_cache_acs_py - wikifier_cache___init___py --> wikifier_cache_barrel_py - wikifier_cache___init___py --> wikifier_cache_diagnostics_py - wikifier_cache___init___py --> wikifier_cache_streaming_py - wikifier_cache___init___py --> wikifier_contracts_py - wikifier_cache_files_py -.-> hashlib - wikifier_cache_files_py -.-> pathlib - wikifier_cache_files_py -.-> typing - wikifier_cache_files_py --> wikifier_cache_io_py - wikifier_cache_io_py -.-> json - wikifier_cache_io_py -.-> os - wikifier_cache_io_py -.-> sys - wikifier_cache_io_py -.-> traceback - wikifier_cache_io_py -.-> pathlib - wikifier_cache_io_py -.-> typing - wikifier_cache_io_py -.-> wikifier - wikifier_health_impl_py -.-> hashlib - wikifier_health_impl_py -.-> json - wikifier_health_impl_py -.-> os - wikifier_health_impl_py -.-> re - wikifier_health_impl_py -.-> sys - wikifier_health_impl_py -.-> dataclasses - wikifier_health_impl_py -.-> datetime - wikifier_health_impl_py -.-> pathlib - wikifier_health_impl_py -.-> typing - wikifier_health_impl_py -.-> _ - wikifier_health_pkg___init___py --> wikifier_health_impl_py - wikifier_mcp_server_impl_py -.-> subprocess - wikifier_mcp_server_impl_py -.-> re - wikifier_mcp_server_impl_py -.-> os - wikifier_mcp_server_impl_py -.-> sys - wikifier_mcp_server_impl_py -.-> json - wikifier_mcp_server_impl_py -.-> wikifier_import_cache - wikifier_mcp_server_impl_py -.-> time - wikifier_mcp_server_impl_py -.-> importlib - wikifier_mcp_server_impl_py -.-> argparse - wikifier_mcp_server_impl_py -.-> mcp_server_fastmcp - wikifier_mcp_server_impl_py -.-> pydantic - wikifier_mcp_server_impl_py -.-> pathlib - wikifier_mcp_server_impl_py -.-> typing - wikifier_mcp_server_impl_py -.-> datetime - wikifier_mcp_server_impl_py --> wikifier_mcp_deadline_py - wikifier_mcp_server_impl_py -.-> wikifier_cli - wikifier_mcp_server_impl_py -. ? .-> _wikifier_health_ - wikifier_mcp_tools__common_py -.-> pathlib - wikifier_mcp_tools__common_py -.-> typing - wikifier_mcp_tools__common_py -.-> wikifier_api - wikifier_mcp_tools_intel_py -.-> typing - wikifier_mcp_tools_intel_py --> wikifier_mcp_tools__common_py - wikifier_mcp_tools_status_py -.-> typing - wikifier_mcp_tools_status_py --> wikifier_mcp_tools__common_py - wikifier_mcp_tools_status_py -.-> wikifier - wikifier_mcp_tools_workflow_py -.-> typing - wikifier_mcp_tools_workflow_py -.-> wikifier_api - wikifier_parsers_bree___init___py --> wikifier_parsers_bree__bree_py - wikifier_parsers_bree__bree_py -.-> json - wikifier_parsers_bree__bree_py -.-> re - wikifier_parsers_bree__bree_py -.-> warnings - wikifier_parsers_bree__bree_py -.-> hashlib - wikifier_parsers_bree__bree_py -.-> os - wikifier_parsers_bree__bree_py -.-> time - wikifier_parsers_bree__bree_py -.-> dataclasses - wikifier_parsers_bree__bree_py -.-> pathlib - wikifier_parsers_bree__bree_py -.-> typing - wikifier_parsers_bree__bree_py -.-> wikifier_parsers_project_root - wikifier_parsers_bree__bree_py -.-> wikifier_parsers_resolution - wikifier_parsers_bree__bree_py -.-> wikifier_resolution - wikifier_parsers_bree__bree_py -.-> wikifier_parsers - wikifier_cache__core_py -.-> json - wikifier_cache__core_py -.-> os - wikifier_cache__core_py -.-> time - wikifier_cache__core_py -.-> hashlib - wikifier_cache__core_py -.-> pathlib - wikifier_cache__core_py -.-> typing - wikifier_cache__core_py -.-> collections - wikifier_cache__core_py -.-> datetime - wikifier_cache__core_py -.-> __ - wikifier_cache__core_py --> wikifier_contracts_py - wikifier_cache__core_py --> wikifier_resolution_py - wikifier_cache__core_py --> wikifier_cache_io_py - wikifier_cache__core_py --> wikifier_cache_files_py - wikifier_cache__core_py --> wikifier_parsers_bree___init___py - wikifier_cache__core_py -.-> dataclasses - wikifier_cache__core_py --> wikifier_project_root_py - wikifier_cache__core_py --> wikifier_parsers___init___py - wikifier_cache_acs_py --> wikifier_cache__core_py - wikifier_cache_barrel_py --> wikifier_cache__core_py - wikifier_cache_cycles_py --> wikifier_cache__core_py - wikifier_cache_diagnostics_py --> wikifier_cache__core_py - wikifier_cache_graph_py --> wikifier_cache__core_py - wikifier_cache_streaming_py --> wikifier_cache__core_py - wikifier_mcp_deadline_py -.-> os - wikifier_mcp_deadline_py -.-> threading - wikifier_mcp_deadline_py -.-> typing - wikifier_parsers__ldsi_py -.-> re - wikifier_parsers__ldsi_py -.-> typing - tests_test_plan_2026_08_27_py -.-> importlib - tests_test_plan_2026_08_27_py -.-> inspect - tests_test_plan_2026_08_27_py -.-> json - tests_test_plan_2026_08_27_py -.-> os - tests_test_plan_2026_08_27_py -.-> subprocess - tests_test_plan_2026_08_27_py -.-> sys - tests_test_plan_2026_08_27_py -.-> unittest - tests_test_plan_2026_08_27_py -.-> mcp - tests_test_plan_2026_08_27_py -.-> wikifier_parsers_bree - tests_test_plan_2026_08_27_py -.-> wikifier - tests_test_plan_2026_08_27_py -.-> pathlib - tests_test_plan_2026_08_27_py -.-> tests__base - tests_test_plan_2026_08_27_py -.-> wikifier_api - tests_test_plan_2026_08_27_py -.-> wikifier_mcp_deadline - tests_test_plan_2026_08_27_py -.-> wikifier_mcp_server_impl - tests_test_plan_2026_08_27_py -.-> wikifier_candidates - tests_test_plan_2026_08_27_py -.-> wikifier_health_impl - tests_test_plan_2026_08_27_py -.-> wikifier_parsers_javascript - tests_test_plan_2026_08_27_py -.-> wikifier_parsers_python - tests_test_plan_2026_08_27_py -. ? .-> _wikifier_health_ - tests_test_plan_2026_08_27_py -. ? .-> _wikifier_parsers_python_ + wikifier_serve_py -.-> _ + tests_test_library_map_honesty_py -.-> json + tests_test_library_map_honesty_py -.-> re + tests_test_library_map_honesty_py -.-> unittest + tests_test_library_map_honesty_py -.-> pathlib + tests_test_library_map_honesty_py -.-> tests__base + tests_test_library_map_honesty_py -.-> wikifier_library + tests_test_library_map_honesty_py -.-> wikifier_agent_loop + tests_test_library_map_honesty_py -.-> wikifier tests__base_py -.-> os tests__base_py -.-> sys tests__base_py -.-> tempfile @@ -775,6 +745,26 @@ graph TD tests_test_parsers_py -.-> tests__base tests_test_parsers_py -.-> wikifier_parsers_python tests_test_parsers_py -.-> wikifier_parsers_javascript + tests_test_plan_2026_08_27_py -.-> importlib + tests_test_plan_2026_08_27_py -.-> inspect + tests_test_plan_2026_08_27_py -.-> json + tests_test_plan_2026_08_27_py -.-> os + tests_test_plan_2026_08_27_py -.-> subprocess + tests_test_plan_2026_08_27_py -.-> sys + tests_test_plan_2026_08_27_py -.-> unittest + tests_test_plan_2026_08_27_py -.-> wikifier_parsers_bree + tests_test_plan_2026_08_27_py -.-> wikifier + tests_test_plan_2026_08_27_py -.-> pathlib + tests_test_plan_2026_08_27_py -.-> tests__base + tests_test_plan_2026_08_27_py -.-> wikifier_api + tests_test_plan_2026_08_27_py -.-> wikifier_mcp_deadline + tests_test_plan_2026_08_27_py -.-> wikifier_mcp_status_ops + tests_test_plan_2026_08_27_py -.-> wikifier_candidates + tests_test_plan_2026_08_27_py -.-> wikifier_health_impl + tests_test_plan_2026_08_27_py -.-> wikifier_parsers_javascript + tests_test_plan_2026_08_27_py -.-> wikifier_parsers_python + tests_test_plan_2026_08_27_py -. ? .-> _wikifier_health_ + tests_test_plan_2026_08_27_py -. ? .-> _wikifier_parsers_python_ tests_test_selftest_wrappers_py -.-> runpy tests_test_selftest_wrappers_py -.-> unittest tests_test_selftest_wrappers_py -.-> pathlib @@ -788,7 +778,7 @@ graph TD tests_test_walk_coverage_resolvers_py -.-> wikifier_agent_loop tests_test_walk_coverage_resolvers_py -.-> wikifier_parsers classDef external fill:#eeeeee,stroke:#888888,stroke-dasharray: 3 3 - class _,__,_wikifier_health_,_wikifier_import_cache_impl_,_wikifier_mcp_server_,_wikifier_parsers_python_,argparse,ast,base64,collections,contextlib,dataclasses,datetime,enum,fcntl,fnmatch,functools,hashlib,http_server,importlib,importlib_resources,inspect,io,json,mcp,mcp_server_fastmcp,modname____name__,msvcrt,name,os,pathlib,platform,pydantic,re,runpy,shutil,signal,sqlite3,subprocess,sys,tempfile,tests__base,textwrap,threading,time,traceback,typing,unittest,warnings,wikifier_agent_loop,wikifier_api,wikifier_cache,wikifier_cache_store,wikifier_candidates,wikifier_cli,wikifier_contracts,wikifier_diagnostics,wikifier_health,wikifier_health_impl,wikifier_import_cache,wikifier_library,wikifier_mcp_deadline,wikifier_mcp_server_impl,wikifier_parsers_bree,wikifier_parsers_cdia,wikifier_parsers_javascript,wikifier_parsers_python,wikifier_project_root,wikifier_resolution external + class _,__,__project_root,__resolution,_wikifier_health_,_wikifier_import_cache_impl_,_wikifier_mcp_server_,_wikifier_parsers_python_,argparse,ast,base64,collections,contextlib,dataclasses,datetime,enum,fcntl,fnmatch,functools,hashlib,http_server,importlib,importlib_resources,inspect,io,json,mcp,mcp_server_fastmcp,modname____name__,msvcrt,name,os,pathlib,platform,pydantic,re,runpy,shutil,signal,sqlite3,subprocess,sys,tempfile,tests__base,textwrap,threading,time,traceback,typing,unittest,warnings,wikifier,wikifier_agent_loop,wikifier_api,wikifier_cache,wikifier_cache_store,wikifier_candidates,wikifier_cli,wikifier_contracts,wikifier_diagnostics,wikifier_health,wikifier_health_impl,wikifier_import_cache,wikifier_library,wikifier_mcp_deadline,wikifier_mcp_status_ops,wikifier_parsers,wikifier_parsers_bree,wikifier_parsers_cdia,wikifier_parsers_javascript,wikifier_parsers_python,wikifier_project_root,wikifier_resolution external ``` ## Resolved Dependencies @@ -926,6 +916,14 @@ graph TD | tests/test_init_seed.py | subprocess → subprocess | medium | | tests/test_init_seed.py | tests._base → tests._base | medium | | tests/test_init_seed.py | unittest → unittest | medium | +| tests/test_library_map_honesty.py | json → json | medium | +| tests/test_library_map_honesty.py | pathlib → pathlib | medium | +| tests/test_library_map_honesty.py | re → re | medium | +| tests/test_library_map_honesty.py | tests._base → tests._base | medium | +| tests/test_library_map_honesty.py | unittest → unittest | medium | +| tests/test_library_map_honesty.py | wikifier → wikifier | medium | +| tests/test_library_map_honesty.py | wikifier.agent_loop → wikifier.agent_loop | medium | +| tests/test_library_map_honesty.py | wikifier.library → wikifier.library | medium | | tests/test_multi_lang_parsers.py | "wikifier.health" → "wikifier.health" | low | | tests/test_multi_lang_parsers.py | importlib → importlib | medium | | tests/test_multi_lang_parsers.py | os → os | medium | @@ -946,7 +944,6 @@ graph TD | tests/test_plan_2026_08_27.py | importlib → importlib | medium | | tests/test_plan_2026_08_27.py | inspect → inspect | medium | | tests/test_plan_2026_08_27.py | json → json | medium | -| tests/test_plan_2026_08_27.py | mcp → mcp | medium | | tests/test_plan_2026_08_27.py | os → os | medium | | tests/test_plan_2026_08_27.py | pathlib → pathlib | medium | | tests/test_plan_2026_08_27.py | subprocess → subprocess | medium | @@ -958,7 +955,7 @@ graph TD | tests/test_plan_2026_08_27.py | wikifier.candidates → wikifier.candidates | medium | | tests/test_plan_2026_08_27.py | wikifier.health_impl → wikifier.health_impl | medium | | tests/test_plan_2026_08_27.py | wikifier.mcp.deadline → wikifier.mcp.deadline | medium | -| tests/test_plan_2026_08_27.py | wikifier.mcp.server_impl → wikifier.mcp.server_impl | medium | +| tests/test_plan_2026_08_27.py | wikifier.mcp.status_ops → wikifier.mcp.status_ops | medium | | tests/test_plan_2026_08_27.py | wikifier.parsers.bree → wikifier.parsers.bree | medium | | tests/test_plan_2026_08_27.py | wikifier.parsers.javascript → wikifier.parsers.javascript | medium | | tests/test_plan_2026_08_27.py | wikifier.parsers.python → wikifier.parsers.python | medium | @@ -1039,7 +1036,7 @@ graph TD | wikifier/cache/files.py | pathlib → pathlib | medium | | wikifier/cache/files.py | typing → typing | medium | | wikifier/cache/graph.py | ._core → wikifier/cache/_core.py | high | -| wikifier/cache/io.py | .. → wikifier | medium | +| wikifier/cache/io.py | .. → .. | medium | | wikifier/cache/io.py | json → json | medium | | wikifier/cache/io.py | os → os | medium | | wikifier/cache/io.py | pathlib → pathlib | medium | @@ -1077,7 +1074,7 @@ graph TD | wikifier/contracts.py | json → json | medium | | wikifier/contracts.py | pathlib → pathlib | medium | | wikifier/contracts.py | typing → typing | medium | -| wikifier/daemon.py | . → wikifier | medium | +| wikifier/daemon.py | . → . | medium | | wikifier/daemon.py | .cli → wikifier/cli.py | high | | wikifier/daemon.py | datetime → datetime | medium | | wikifier/daemon.py | json → json | medium | @@ -1093,16 +1090,6 @@ graph TD | wikifier/diagnostics.py | enum → enum | medium | | wikifier/diagnostics.py | json → json | medium | | wikifier/diagnostics.py | typing → typing | medium | -| wikifier/health.py | . → wikifier | medium | -| wikifier/health.py | dataclasses → dataclasses | medium | -| wikifier/health.py | datetime → datetime | medium | -| wikifier/health.py | hashlib → hashlib | medium | -| wikifier/health.py | json → json | medium | -| wikifier/health.py | os → os | medium | -| wikifier/health.py | pathlib → pathlib | medium | -| wikifier/health.py | re → re | medium | -| wikifier/health.py | sys → sys | medium | -| wikifier/health.py | typing → typing | medium | | wikifier/health_impl.py | . → . | medium | | wikifier/health_impl.py | dataclasses → dataclasses | medium | | wikifier/health_impl.py | datetime → datetime | medium | @@ -1137,6 +1124,7 @@ graph TD | wikifier/mcp/server.py | .server_impl → wikifier/mcp/server_impl.py | high | | wikifier/mcp/server_impl.py | "wikifier.health" → "wikifier.health" | low | | wikifier/mcp/server_impl.py | .deadline → wikifier/mcp/deadline.py | high | +| wikifier/mcp/server_impl.py | .status_ops → wikifier/mcp/status_ops.py | high | | wikifier/mcp/server_impl.py | argparse → argparse | medium | | wikifier/mcp/server_impl.py | datetime → datetime | medium | | wikifier/mcp/server_impl.py | importlib → importlib | medium | @@ -1152,16 +1140,15 @@ graph TD | wikifier/mcp/server_impl.py | typing → typing | medium | | wikifier/mcp/server_impl.py | wikifier.cli → wikifier.cli | medium | | wikifier/mcp/server_impl.py | wikifier.import_cache → wikifier.import_cache | medium | +| wikifier/mcp/status_ops.py | "wikifier.health" → "wikifier.health" | low | +| wikifier/mcp/status_ops.py | .deadline → wikifier/mcp/deadline.py | high | +| wikifier/mcp/status_ops.py | importlib → importlib | medium | +| wikifier/mcp/status_ops.py | pathlib → pathlib | medium | +| wikifier/mcp/status_ops.py | typing → typing | medium | +| wikifier/mcp/status_ops.py | wikifier.import_cache → wikifier.import_cache | medium | | wikifier/mcp/tools/_common.py | pathlib → pathlib | medium | | wikifier/mcp/tools/_common.py | typing → typing | medium | | wikifier/mcp/tools/_common.py | wikifier.api → wikifier.api | medium | -| wikifier/mcp/tools/intel.py | ._common → wikifier/mcp/tools/_common.py | high | -| wikifier/mcp/tools/intel.py | typing → typing | medium | -| wikifier/mcp/tools/status.py | ._common → wikifier/mcp/tools/_common.py | high | -| wikifier/mcp/tools/status.py | typing → typing | medium | -| wikifier/mcp/tools/status.py | wikifier → wikifier | medium | -| wikifier/mcp/tools/workflow.py | typing → typing | medium | -| wikifier/mcp/tools/workflow.py | wikifier.api → wikifier.api | medium | | wikifier/parsers/__init__.py | importlib → importlib | medium | | wikifier/parsers/__init__.py | modname, __name__ → modname, __name__ | low | | wikifier/parsers/__init__.py | typing → typing | medium | @@ -1170,9 +1157,9 @@ graph TD | wikifier/parsers/_ldsi.py | re → re | medium | | wikifier/parsers/_ldsi.py | typing → typing | medium | | wikifier/parsers/bree/__init__.py | ._bree → wikifier/parsers/bree/_bree.py | high | -| wikifier/parsers/bree/_bree.py | .. → wikifier.parsers | medium | -| wikifier/parsers/bree/_bree.py | ..project_root → wikifier.parsers.project_root | medium | -| wikifier/parsers/bree/_bree.py | ..resolution → wikifier.parsers.resolution | medium | +| wikifier/parsers/bree/_bree.py | .. → .. | medium | +| wikifier/parsers/bree/_bree.py | ..project_root → ..project_root | medium | +| wikifier/parsers/bree/_bree.py | ..resolution → ..resolution | medium | | wikifier/parsers/bree/_bree.py | dataclasses → dataclasses | medium | | wikifier/parsers/bree/_bree.py | hashlib → hashlib | medium | | wikifier/parsers/bree/_bree.py | json → json | medium | @@ -1253,7 +1240,7 @@ graph TD | wikifier/resolution.py | re → re | medium | | wikifier/resolution.py | time → time | medium | | wikifier/resolution.py | typing → typing | medium | -| wikifier/serve.py | . → wikifier | medium | +| wikifier/serve.py | . → . | medium | | wikifier/serve.py | .cli → wikifier/cli.py | high | | wikifier/serve.py | http.server → http.server | medium | | wikifier/serve.py | json → json | medium | @@ -1270,10 +1257,10 @@ graph TD ## ACS Risk Snapshot -**Scored edges**: 459 | **avg_confidence**: 0.51 | **actionable_low_conf**: 42 | raw low-conf (telemetry): 397 (threshold 0.65) +**Scored edges**: 668 | **avg_confidence**: 0.51 | **actionable_low_conf**: 58 | raw low-conf (telemetry): 578 (threshold 0.65) **Agent work queue**: use `actionable_low_conf_edges` + `reason_code_counts` / `agent_signal=investigate` only — do **not** thrash on raw `low_conf_edges` (includes external/bare). -**reason_code_counts**: external_or_bare:327, high_confidence_ok:62, low_confidence_internal:42, dynamic_literal:28 -**Top risk reasons**: base:medium:368, no_resolved_path:368, base:high:62, base:low:29 +**reason_code_counts**: external_or_bare:483, high_confidence_ok:90, unresolved_project:58, dynamic_literal:37 +**Top risk reasons**: base:medium:540, no_resolved_path:540, base:high:90, base:low:38 **Sample low-confidence edges (telemetry; prefer actionable)**: 1. Base low (0.05). opaque dynamic expression; high complexity; conditional_dynamic semantics; creative registry_map (LDSI/CDIA); trace: ControlFlowDetector=if. Recommendation: Opaque or high-complexity dynamic resolution — refactor to static import or introduce explicit runtime guard; current edge is unsuitable for static analysis tooling. 2. Base medium (0.48). unresolved target. Recommendation: Low-confidence or fragile edge — review the concrete usage site and consider hardening the import (or pin resolution) before trusting the dependency for automation. @@ -1281,19 +1268,19 @@ graph TD ## Reverse Dependencies ("Who depends on me") -**Targets with dependents**: 34 | **Total reverse edges**: 67 +**Targets with dependents**: 30 | **Total reverse edges**: 60 **High-impact modules (most reverse dependents)**: - `wikifier/cache/_core.py` ← 6 files depend on it (e.g. wikifier/cache/acs.py, wikifier/cache/barrel.py, wikifier/cache/cycles.py, wikifier/cache/diagnostics.py) - `wikifier/contracts.py` ← 6 files depend on it (e.g. wikifier/__init__.py, wikifier/api.py, wikifier/cache/__init__.py, wikifier/cache/_core.py) - `wikifier/parsers/_edge.py` ← 5 files depend on it (e.g. wikifier/parsers/c_cpp.py, wikifier/parsers/csharp.py, wikifier/parsers/go_lang.py, wikifier/parsers/java.py) -- `wikifier` ← 4 files depend on it (e.g. wikifier/cache/io.py, wikifier/daemon.py, wikifier/health.py, wikifier/serve.py) - `wikifier/cli.py` ← 4 files depend on it (e.g. wikifier/__init__.py, wikifier/__main__.py, wikifier/daemon.py, wikifier/serve.py) - `wikifier/project_root.py` ← 4 files depend on it (e.g. wikifier/agent_loop.py, wikifier/api.py, wikifier/cache/_core.py, wikifier/parsers/javascript.py) - `wikifier/cache/io.py` ← 3 files depend on it (e.g. wikifier/cache/__init__.py, wikifier/cache/_core.py, wikifier/cache/files.py) - `wikifier/resolution.py` ← 3 files depend on it (e.g. wikifier/api.py, wikifier/cache/_core.py, wikifier/parsers/javascript.py) - `wikifier/cache/files.py` ← 2 files depend on it (e.g. wikifier/cache/__init__.py, wikifier/cache/_core.py) -- `wikifier/mcp/tools/_common.py` ← 2 files depend on it (e.g. wikifier/mcp/tools/intel.py, wikifier/mcp/tools/status.py) +- `wikifier/mcp/deadline.py` ← 2 files depend on it (e.g. wikifier/mcp/server_impl.py, wikifier/mcp/status_ops.py) +- `wikifier/parsers/__init__.py` ← 2 files depend on it (e.g. wikifier/api.py, wikifier/cache/_core.py) ## Barrel Expansions @@ -1305,18 +1292,42 @@ graph TD ## Conditional & Dynamic Intelligence -**Conditional imports detected**: 38 -**Dynamic imports detected**: 40 +**Conditional imports detected**: 36 +**Dynamic imports detected**: 38 Sample conditional imports (fragile / feature-flagged paths): - `wikifier/agent_loop.py` → `"wikifier.health"` (ctx: ) -- `wikifier/parsers/__init__.py` → `modname, __name__` (ctx: ) -- `wikifier/mcp/server_impl.py` → `"wikifier.health"` (ctx: ) +- `wikifier/cache/_core.py` → `import_module(" in expl or "__import__(" in expl or "importlib.import_module" in expl: + return True + + + if dtype in ("static", "string", "literal"): + + i` (ctx: ) +- `wikifier/cache/_core.py` → `__import__(" in expl or "importlib.import_module" in expl: + return True + + + if dtype in ("static", "string", "literal"): + + if (raw.startswith("\"") and` (ctx: ) - `wikifier/mcp/server_impl.py` → `"wikifier.health"` (ctx: ) - `wikifier/mcp/server_impl.py` → `"wikifier.health"` (ctx: ) Sample dynamic imports (runtime / template-driven): - `wikifier/agent_loop.py` → `"wikifier.health"` (type: static) -- `wikifier/parsers/__init__.py` → `modname, __name__` (type: unknown) -- `wikifier/mcp/server_impl.py` → `"wikifier.health"` (type: static) +- `wikifier/cache/_core.py` → `import_module(" in expl or "__import__(" in expl or "importlib.import_module" in expl: + return True + + + if dtype in ("static", "string", "literal"): + + i` (type: expression) +- `wikifier/cache/_core.py` → `__import__(" in expl or "importlib.import_module" in expl: + return True + + + if dtype in ("static", "string", "literal"): + + if (raw.startswith("\"") and` (type: expression) - `wikifier/mcp/server_impl.py` → `"wikifier.health"` (type: static) - `wikifier/mcp/server_impl.py` → `"wikifier.health"` (type: static) diff --git a/skills/run.md b/skills/run.md index 17d3281..e34556f 100644 --- a/skills/run.md +++ b/skills/run.md @@ -1,13 +1,13 @@ -# Wikifier Agent Protocol v0.6 +# Wikifier Agent Protocol v0.6.1 **Formerly "Wikifier Skills & Commands". This is the authoritative, versioned specification for agent behavior when using Wikifier.** -**Version**: v0.6 (v4.2.0 real-pipeline + reliability update; package current **4.6.x**, live `__version__` in `wikifier/__init__.py`) -**Date**: 2026-06-10 (package notes refreshed 2026-08-01; gap-closure contract 2026-07-09) -**Status**: Active. Supersedes v0.5. +**Version**: v0.6.1 (additive 4.6.x I/O notes on v0.6; package current **4.6.x**, live `__version__` in `wikifier/__init__.py`) +**Date**: 2026-09-11 (v0.6 dated 2026-06-10; package notes refreshed 2026-08-01; gap-closure 2026-07-09) +**Status**: Active. Supersedes v0.6. v0.6 agent behavior keeps working (additive fields only). **See also**: `README.md`, `Findings/gap-closure-report.md`, `Findings/gap-amendment-plan-2026-08-01.md`, and the library in wikifier/. -**Package 4.6.x + gap-closure notes (additive; protocol still v0.6):** +**Package 4.6.x + gap-closure notes (additive; folded into v0.6.1):** - File Tree + `wikifier serve`; MCP status/attention use library + emoji (not `[GREEN]` tags). - **First-run:** `init` → lean `monitored_paths.txt` + `map_paths.txt` (default active root `src/`, not bare `.`) → `update-maps` → `health --summary` → `suggest_next_actions`. Map is automatic; wiki *prose* is agent-filled over time. - **`session_bootstrap` readiness:** message embeds the readiness tier. `blocked` is not a crash — see **§ Readiness blocked**. Hard blockers = missing map/health (or severe ghosts). Bare `.` monitor alone → `map_ok_scope_risk` when map+health exist (scope warnings / fix_scope), not the same tier as missing map. Unattended ops require **`readiness=ready_for_daemon`**, not `health_score=Map Ready` alone. @@ -20,7 +20,7 @@ - **Dual scope:** `monitored_paths` = check-changes/health scope (keep lean). `update-maps --directory=` / `--max-files=` = map walk. Never set `project_root` to a multi-repo parent (e.g. `cloned_sample_projects`). - **CLI target:** `wikifier --target /abs/project health --summary` (flags stripped before the command). Or `WIKIFIER_PROJECT_ROOT=…`. - **Long-horizon:** `wikifier autonomous-status` (or `readiness`) before unattended runs; daemon writes `.wikifier_staging/daemon_heartbeat.json`. Soak ≥72h is still evidence work, not automatic. -- **Deletions:** `record-deletion` + ghost detection. **Languages:** py/js/ts/rust/go/c/c#/java (regex). journal/pending = audit queue, not Jira. +- **Deletions:** `record-deletion` + ghost detection. **Languages:** two-tier (see table below). journal/pending = audit queue, not Jira. - **Huge monorepos:** lean `monitored_paths.txt` (not bare `.`). `WIKIFIER_CHECK_CHANGES_MAX` default 2000. Hygiene: `seed-health`, `prune-pending`, `prune-health`. - **Monitor/daemon:** mtime heartbeat; agents still own wiki/mark-green. `WIKIFIER_DAEMON_MAPS_INTERVAL` default 600s; `WIKIFIER_DAEMON_MAPS=0` for check-only. - Health module: `importlib.import_module("wikifier.health")` or `wikifier.health_module` — `from wikifier import health` is the *function*. @@ -32,6 +32,21 @@ - A POSIX lock self-deadlock in library `record_change`/`mark_green`/`check_changes` was fixed (locking is now re-entrant per process). MCP timeouts on those tools should no longer occur; the CLI fallback guidance below remains valid as defense in depth. - A stdlib-only test suite exists: `python -m unittest discover tests` (run it when working on Wikifier itself). +**v0.6.1 migration notes (package 4.6.x; additive on v0.6)** — no mandatory I/O break; tolerate new keys: +- **Readiness tiers** (`session_bootstrap.readiness`): `blocked` / `map_ok_scope_risk` / `ready_for_daemon` / `ready_with_agent_wiki_work` / `not_ready`. Unattended work needs `ready_for_daemon`, not `health_score=Map Ready` alone. +- **`map_paths.txt` vs `monitored_paths.txt`:** map package roots vs wiki/health watch. Independent. Wiki-only monitor lists do **not** define the map. +- **ACS v1.3:** `actionable_low_conf_edges`, `reason_code_counts`, `agent_signal` (`skip`|`investigate`). Never thrash on raw `low_conf_edges`. +- **Index-first maps:** `index_first_dirty` / `candidates_reused` on `update_maps`. `success: true` ≠ map complete — use `map_coverage.complete`. +- **`record_change`:** additive `needs_mark_green: true`; stays Yellow until `mark_green`. +- **`session_bootstrap` cache fields:** `cache_backend` is `sqlite` | `sqlite+json` | `json` | `none`. **`none` means no sqlite/json file at read time.** An empty SQLite file (schema only, `files` table count = 0) is still `sqlite`, not `none`. Additive `cache_empty` (bool) and `cache_files_indexed` (int) make that split explicit. ACS zeros + `cache_empty: true` means “no pairs yet”, not “no backend”. `cache-status` reports the file backend; bootstrap used to leave `cache_backend: "none"` after creating the empty stub — that is fixed; do not equate the two tools without checking `cache_empty`. +- **Committed `library.md`:** regenerate with `update-maps`; do not hand-edit. Nodes must be files on disk. +- **Language depth (G9):** deep/ACS = Python + JS/TS; Rust/Go/C/C++/C#/Java are regex hints. + +| Depth | Languages | Trust | +|-------|-----------|--------| +| Deep / ACS | Python, JS/TS | CDIA, BREE, scored resolve, ACS work queue | +| Regex hint | Rust, Go, C/C++, C#, Java | `use`/`import`/`#include`/`using` smokes — not cargo/`go.mod`/classpath/`-I` | + **Core design**: Token-efficient agent-to-agent wiki. Agents use it to look up files (health matrix + file wikis + BRC + stele chunks instead of full sources), autonomously update wiki summaries, and create new ones as work progresses. **It should not be used for anything more than that.** This protocol + the Python package + MCP server form the bridge for consistent, low-ambiguity agent operation on real external projects. @@ -140,7 +155,7 @@ See also: Findings note `Findings/readiness-blocked-bare-monitor-2026-07.md`. **Copy this exact block into the system prompt or the very first instruction of every new LLM session that uses Wikifier:** ``` -You are now operating inside a Wikifier-managed codebase (Agent Protocol v0.6 — package 4.6.x). +You are now operating inside a Wikifier-managed codebase (Agent Protocol v0.6.1 — package 4.6.x). This is strictly an agent-to-agent wiki for token saving: map lookup (health + file wikis + deps) instead of full sources; selective wiki updates; not a human docs product or Jira. diff --git a/tests/test_library_map_honesty.py b/tests/test_library_map_honesty.py new file mode 100644 index 0000000..27b39d7 --- /dev/null +++ b/tests/test_library_map_honesty.py @@ -0,0 +1,195 @@ +"""library.md must name only files that exist on disk. + +Drives the shipped generator and the committed dogfood artifact — not mocks. +""" +from __future__ import annotations + +import json +import re +import unittest +from pathlib import Path + +from tests._base import REPO_ROOT, TempProjectTestCase +from wikifier.library import generate_library_md + +# 4.6.10 leftovers that must not reappear in the committed map. +GONE_PATHS = ( + "wikifier/mcp/tools/intel.py", + "wikifier/mcp/tools/status.py", + "wikifier/mcp/tools/workflow.py", + "wikifier/parsers/javascript/_parser.py", + "wikifier/parsers/javascript/__init__.py", + "wikifier/health.py", + "wikifier/mcp/server_backup.py", + "wikifier/parsers/bree.py", +) + +GONE_MERMAID_IDS = ( + "wikifier_mcp_tools_intel_py", + "wikifier_mcp_tools_status_py", + "wikifier_mcp_tools_workflow_py", + "wikifier_parsers_javascript__parser_py", + "wikifier_health_py", + "wikifier_mcp_server_backup_py", + "wikifier_parsers_bree_py", +) + +# Project-relative source paths as they appear in tables / reverse-deps / prose. +_REL_PATH_RE = re.compile( + r"(?:`)?((?:wikifier|tests|skills|Findings|docs|\.github)" + r"/[A-Za-z0-9_./+-]+\.[A-Za-z0-9.]+)" +) + + +def _parse_file_tree_paths(text: str): + """Reconstruct project-relative paths from the File Tree fence.""" + m = re.search(r"## File Tree.*?```text\n(.*?)```", text, re.S) + if not m: + return [] + paths = [] + stack = [] # (depth, dir_name) + for line in m.group(1).splitlines(): + if not line.strip() or line.startswith("…"): + continue + if re.match(r"^[^│├└].*/\s+\(\d+ files\)\s*$", line): + continue + mm = re.match(r"^([ │]*)(?:├── |└── )(.+)$", line) + if not mm: + continue + prefix, rest = mm.groups() + depth = len(prefix) // 4 + name = rest.split(" — ", 1)[0].strip() + if name.startswith("…"): + continue + name = re.sub(r"\s+\(\d+ files\)\s*$", "", name) + while stack and stack[-1][0] >= depth: + stack.pop() + if name.endswith("/"): + stack.append((depth, name.rstrip("/"))) + continue + parts = [d[1] for d in stack] + [name] + paths.append("/".join(parts)) + return paths + + +def _named_rel_paths(text: str): + found = set(_parse_file_tree_paths(text)) + for m in _REL_PATH_RE.finditer(text): + found.add(m.group(1).rstrip("`")) + return sorted(found) + + +class TestGenerateLibraryOmitsMissingFiles(TempProjectTestCase): + def test_generate_library_md_omits_missing_cache_keys(self): + self.write("pkg/live.py", "import os\n") + cache = { + "pkg/live.py": { + "mtime": 1, + "resolved_pairs": [{ + "raw": "os", + "resolved": "", + "confidence": "medium", + }], + }, + "pkg/gone.py": { + "mtime": 1, + "resolved_pairs": [{ + "raw": "./helper", + "resolved": "pkg/helper.py", + "confidence": "high", + }], + }, + "_reverse_dependencies": { + "pkg/helper.py": ["pkg/gone.py", "pkg/live.py"], + "pkg/live.py": ["pkg/gone.py"], + }, + } + md = generate_library_md(self.root, cache) + self.assertIn("live.py", md) + self.assertNotIn("gone.py", md) + self.assertNotIn("helper.py", md) + self.assertNotIn("pkg/gone.py", md) + self.assertNotIn("pkg/helper.py", md) + + def test_file_tree_prefers_wiki_not_health_reason(self): + self.write("pkg/mod.py", "x = 1\n") + self.write( + "pkg/mod.py.wiki.md", + "# pkg/mod.py\n\n## Purpose\n\nImport parser helper.\n", + ) + health = { + "entries": { + "pkg/mod.py": { + "status": "🟢 Green", + "reason": "4.6.13 plan aligned", + } + } + } + (self.root / "file_health.json").write_text( + json.dumps(health), encoding="utf-8" + ) + cache = {"pkg/mod.py": {"mtime": 1, "resolved_pairs": []}} + md = generate_library_md(self.root, cache) + self.assertIn("Import parser helper", md) + self.assertNotIn("plan aligned", md) + + def test_wiki_role_colon_inside_bold(self): + self.write("pkg/mod.py", "x = 1\n") + self.write( + "pkg/mod.py.wiki.md", + "# pkg/mod.py\n\n**Role:** Gap-closure regressions.\n", + ) + md = generate_library_md( + self.root, {"pkg/mod.py": {"mtime": 1, "resolved_pairs": []}} + ) + self.assertIn("Gap-closure regressions.", md) + self.assertNotIn("Role:**", md) + + +class TestCommittedLibraryMdMatchesTree(unittest.TestCase): + def test_library_md_paths_exist_on_disk(self): + lib = REPO_ROOT / "library.md" + self.assertTrue(lib.is_file(), "committed library.md missing") + text = lib.read_text(encoding="utf-8") + missing = [] + for rel in _named_rel_paths(text): + if not (REPO_ROOT / rel).is_file(): + missing.append(rel) + self.assertEqual( + missing, + [], + "library.md names paths that are not files on disk: {0}".format( + missing[:20] + ), + ) + + def test_library_md_omits_deleted_4_6_10_leftovers(self): + text = (REPO_ROOT / "library.md").read_text(encoding="utf-8") + present = [p for p in GONE_PATHS if p in text] + self.assertEqual(present, [], present) + ids = [i for i in GONE_MERMAID_IDS if i in text] + self.assertEqual(ids, [], ids) + + +class TestBootstrapCacheBackendHonesty(TempProjectTestCase): + def test_empty_sqlite_is_not_cache_backend_none(self): + from wikifier.agent_loop import session_bootstrap + from wikifier import cache_store as cs + + boot = session_bootstrap(project_root=self.root) + self.assertTrue(boot.get("success"), boot) + self.assertIn("cache_empty", boot) + self.assertIn("cache_files_indexed", boot) + if cs.has_sqlite(self.root) or cs.json_path(self.root).is_file(): + self.assertNotEqual( + boot.get("cache_backend"), + "none", + "empty sqlite/json store must not report cache_backend=none", + ) + if boot.get("cache_backend") == "none": + self.assertTrue(boot.get("cache_empty")) + self.assertEqual(boot.get("cache_files_indexed"), 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/wikifier/agent_loop.py b/wikifier/agent_loop.py index a4c4c26..3c8e690 100644 --- a/wikifier/agent_loop.py +++ b/wikifier/agent_loop.py @@ -648,8 +648,18 @@ def session_bootstrap( cache = ic.load_cache(root) or {} acs = ic.ensure_acs_summary_persisted(cache, root) or {} cyc = cache.get("_cycles") or {} - if cs is not None and not out.get("cache_backend"): + # Re-read after persist: creating an empty sqlite must not leave "none". + if cs is not None: out["cache_backend"] = cs.backend_name(root) + try: + n = 0 + if cs is not None: + n = len(cs.load_mtime_index(root) or {}) + out["cache_files_indexed"] = n + out["cache_empty"] = n == 0 + except Exception: + out.setdefault("cache_files_indexed", 0) + out.setdefault("cache_empty", True) acs_actionable = int(acs.get("actionable_low_conf_edges") or 0) out["acs"] = { "acs_version": acs.get("acs_version"), diff --git a/wikifier/library.py b/wikifier/library.py index 3703ab7..f248356 100644 --- a/wikifier/library.py +++ b/wikifier/library.py @@ -507,41 +507,95 @@ def _generate_conditional_dynamic_section(cache: Dict[str, Any]) -> List[str]: # --------------------------------------------------------------------------- -# Public API +# Live-path filter (stale cache keys must not become map nodes) # --------------------------------------------------------------------------- -# --------------------------------------------------------------------------- -# File tree (the primary human/agent view of project shape) -# --------------------------------------------------------------------------- +_SOURCE_SUFFIXES = ( + ".py", ".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs", ".mts", ".cts", + ".go", ".rs", ".c", ".h", ".cpp", ".cc", ".cxx", ".hpp", ".hh", + ".cs", ".java", ".md", ".sh", +) -def _clean_reason(reason: str) -> Optional[str]: - """Normalise a health reason into a short description, or None for - auto-yellow boilerplate (it describes the tracking system, not the file).""" - reason = re.sub(r"\s+", " ", str(reason or "")).strip() - if not reason or reason.startswith("mtime changed") or "auto-detected" in reason: - return None - return (reason[:90] + "…") if len(reason) > 91 else reason +def _is_live_file(root: Path, rel: str) -> bool: + rel = str(rel or "").replace("\\", "/").strip() + if not rel or rel.startswith("_") or "\n" in rel: + return False + try: + return Path(root, rel).is_file() + except (OSError, ValueError): + return False -def _load_health_descriptions(root: Path) -> Dict[str, str]: - """file -> short description, from file_health.json or file_health.md. - Projects maintained through the shell workflow only have the .md table - (the JSON is written by the Python health module), so both are read. +def _looks_like_rel_file(rel: str) -> bool: + rel = str(rel or "").replace("\\", "/").strip() + if not rel or rel.startswith("_"): + return False + lower = rel.lower() + return ("/" in rel) or lower.endswith(_SOURCE_SUFFIXES) + + +def _wiki_caption(root: Path, rel: str) -> Optional[str]: + """Short purpose/role line from ``{rel}.wiki.md``, or None. + + Health *reasons* are audit stamps and must not be used as captions. """ - desc: Dict[str, str] = {} + wiki = Path(root, rel + ".wiki.md") + if not wiki.is_file(): + return None + try: + text = wiki.read_text(encoding="utf-8", errors="replace") + except OSError: + return None + lines = text.splitlines() + picked = None + heading_re = re.compile(r"^#{1,6}\s+(purpose|role)\b", re.I) + role_re = re.compile(r"^\*\*role:?\*\*\s*(.*)$", re.I) + for i, line in enumerate(lines): + s = line.strip() + if heading_re.match(s): + for nxt in lines[i + 1:]: + n = nxt.strip() + if not n: + continue + if n.startswith("#"): + break + picked = n.lstrip("-* ").strip() + break + if picked: + break + m2 = role_re.match(s) + if m2 and m2.group(1).strip(): + picked = m2.group(1).strip() + break + if not picked: + for line in lines: + s = line.strip() + if not s or s.startswith("#") or s.startswith(">") or s.startswith("|"): + continue + picked = s.lstrip("-* ").strip() + break + if not picked: + return None + picked = re.sub(r"\s+", " ", picked) + return (picked[:90] + "…") if len(picked) > 91 else picked + + +def _health_tracked_files(root: Path) -> List[str]: + """On-disk files listed in the health matrix (keys only; reasons ignored).""" + tracked: List[str] = [] try: with open(root / "file_health.json", "r", encoding="utf-8") as f: data = json.load(f) entries = data.get("entries", data) if isinstance(data, dict) else {} - for file, e in entries.items(): - r = _clean_reason((e or {}).get("reason")) - if r: - desc[str(file)] = r + for file in entries: + k2 = str(file).rstrip("/") + if k2 and _is_live_file(root, k2): + tracked.append(k2) except Exception: pass - if desc: - return desc + if tracked: + return tracked try: # .md fallback: | File | Status | Last Updated | Reason / Intent | with open(root / "file_health.md", "r", encoding="utf-8") as f: for line in f: @@ -550,12 +604,69 @@ def _load_health_descriptions(root: Path) -> Dict[str, str]: continue parts = [p.strip() for p in line.split("|")] if len(parts) >= 6 and parts[1]: - r = _clean_reason(parts[4]) - if r: - desc[parts[1]] = r + k2 = parts[1].rstrip("/") + if k2 and _is_live_file(root, k2): + tracked.append(k2) except Exception: pass - return desc + return tracked + + +def _live_cache_view(root: Path, cache: Dict[str, Any]) -> Dict[str, Any]: + """Shallow copy dropping per-file entries whose source is missing on disk.""" + if not isinstance(cache, dict): + return {} + out: Dict[str, Any] = {} + for k, v in cache.items(): + if not isinstance(k, str): + continue + if k.startswith("_"): + out[k] = v + continue + if _is_live_file(root, k): + out[k] = v + rev = out.get("_reverse_dependencies") + if isinstance(rev, dict): + new_rev: Dict[str, List[str]] = {} + for tgt, srcs in rev.items(): + tgt_s = str(tgt) + if _looks_like_rel_file(tgt_s) and not _is_live_file(root, tgt_s): + continue + if not isinstance(srcs, list): + continue + live_srcs = [] + for s in srcs: + ss = str(s) + if _looks_like_rel_file(ss) and not _is_live_file(root, ss): + continue + live_srcs.append(ss) + if live_srcs: + new_rev[tgt_s] = live_srcs + out["_reverse_dependencies"] = new_rev + return out + + +def _filter_live_edges( + root: Path, edges: List[Tuple[str, str, str, str, bool]] +) -> List[Tuple[str, str, str, str, bool]]: + """Drop edges whose source (or resolved internal target) is not on disk.""" + out = [] + for src, raw, target, conf, internal in edges: + if _looks_like_rel_file(src) and not _is_live_file(root, src): + continue + if internal and _looks_like_rel_file(target) and not _is_live_file(root, target): + continue + out.append((src, raw, target, conf, internal)) + return out + + +# --------------------------------------------------------------------------- +# Public API +# --------------------------------------------------------------------------- + +# --------------------------------------------------------------------------- +# File tree (the primary human/agent view of project shape) +# --------------------------------------------------------------------------- TREE_DIR_FILE_CAP = 40 # files listed per directory before "… +N more" @@ -574,21 +685,12 @@ def _generate_tree_section(root: Path, cache: Dict[str, Any]) -> List[str]: │ └── python.py └── cli.py — entry point + full update pipeline """ - descriptions = _load_health_descriptions(root) - parsed = {k for k in cache.keys() if isinstance(k, str) and not k.startswith("_")} - # Health keys are free text (audit records may use whole sentences as the - # "file"; some entries point at directories): only real on-disk files — - # or parser-confirmed ones — belong in the tree. - tracked = set() - for k in descriptions: - k2 = k.rstrip("/") - if not k2 or k2 in parsed: - continue - try: - if (root / k2).is_file(): - tracked.add(k2) - except OSError: - continue + parsed = { + k for k in cache.keys() + if isinstance(k, str) and not k.startswith("_") and _is_live_file(root, k) + } + # Health keys may be sentences or directories; only live files belong here. + tracked = {k for k in _health_tracked_files(root) if k not in parsed} files = sorted(parsed | tracked) if not files: return ["## File Tree", "", "```text", @@ -632,15 +734,16 @@ def render(node: Dict[str, Any], prefix: str, path_prefix: str) -> None: out.append(prefix + connector + name + suffix) render(sub, child_prefix, path_prefix + name) else: - d = descriptions.get(path_prefix + name) + d = _wiki_caption(root, path_prefix + name) out.append(prefix + connector + name + ((" — " + d) if d else "")) render(tree, "", "") lines = [ "## File Tree", "", - "> Every parsed/tracked file, organised by folder. Descriptions come from", - "> the agent wiki (file_health). The dependency graph is further below.", + "> Every parsed/tracked file, organised by folder. Captions come from", + "> `*.wiki.md` purpose/role text when present. Health *reasons* are audit", + "> stamps and are not copied here. The dependency graph is further below.", "", "```text", "{0}/ ({1} files)".format(root.name, len(files)), ] @@ -655,7 +758,8 @@ def generate_library_md(root: Path, cache: Dict[str, Any]) -> str: """Render library.md content from an import cache (see module docstring).""" if not isinstance(cache, dict): cache = {} - edges = _collect_edges(cache) + cache = _live_cache_view(root, cache) + edges = _filter_live_edges(root, _collect_edges(cache)) lines = [ "# Library & Imports Map (auto-generated by wikifier update-maps)", @@ -702,8 +806,9 @@ def write_library_md(root: Path, cache: Optional[Dict[str, Any]] = None) -> Dict cache = load_cache(root) if not isinstance(cache, dict): cache = {} - content = generate_library_md(root, cache) - nodes, edges = _graph_stats(cache) + live = _live_cache_view(root, cache) + content = generate_library_md(root, live) + nodes, edges = _graph_stats(live) tmp_path = out_path.with_name(out_path.name + ".tmp") tmp_path.write_text(content, encoding="utf-8") os.replace(str(tmp_path), str(out_path)) diff --git a/wikifier/library.py.wiki.md b/wikifier/library.py.wiki.md new file mode 100644 index 0000000..514667f --- /dev/null +++ b/wikifier/library.py.wiki.md @@ -0,0 +1,7 @@ +# wikifier/library.py + +**Role**: Pure-Python generator for committed `library.md` (file tree, Mermaid, tables, ACS, reverse deps). + +## Purpose + +Render the import map from the cache. Omit cache keys whose source is missing on disk. File-tree captions come from `*.wiki.md` purpose/role text, never health audit reasons. Regenerated by `update-maps`; do not hand-edit `library.md`.