{
  "markdown": "# 🐙 TraceWeave\n\n<!-- mcp-name: io.github.gokeshenzhen/traceweave -->\n\n<p align=\"right\">\n  <strong>English</strong> · <a href=\"https://github.com/gokeshenzhen/TraceWeave/blob/main/README.zh.md\">简体中文</a>\n</p>\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/gokeshenzhen/TraceWeave/main/assets/logo.png\" alt=\"TraceWeave\" width=\"160\">\n</p>\n\n<p align=\"center\">\n  <strong>Workflow-oriented MCP server for evidence-driven RTL simulation debugging</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/gokeshenzhen/TraceWeave/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/gokeshenzhen/TraceWeave/ci.yml?branch=main&style=for-the-badge\" alt=\"CI status\"></a>\n  <a href=\"https://pypi.org/project/traceweave-mcp/\"><img src=\"https://img.shields.io/pypi/v/traceweave-mcp?style=for-the-badge\" alt=\"PyPI version\"></a>\n  <a href=\"https://github.com/gokeshenzhen/TraceWeave/blob/main/LICENSE\"><img src=\"https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge\" alt=\"MIT License\"></a>\n  <a href=\"https://www.python.org/\"><img src=\"https://img.shields.io/badge/python-3.11%2B-blue?style=for-the-badge&logo=python&logoColor=white\" alt=\"Python 3.11+\"></a>\n  <a href=\"https://github.com/gokeshenzhen/TraceWeave/stargazers\"><img src=\"https://img.shields.io/github/stars/gokeshenzhen/TraceWeave?style=for-the-badge\" alt=\"Stars\"></a>\n</p>\n\n<h2 align=\"center\">Connect compile evidence, logs, waveforms, source, and elaborated connectivity in one verifiable debug workflow.</h2>\n\nTraceWeave turns local VCS/Xcelium simulation artifacts into a guided investigation. It discovers the active compile, simulation, and VCD/FSDB waveform inputs; builds the compiled hierarchy and an independent structural-risk view; normalizes failures; runs a whole-design runtime handshake sweep; and recommends the next evidence-gathering call.\n\nFor driver, load, structural-path, and X/Z-source questions, TraceWeave uses a provenance-preserving backend ladder: trusted Verdi NPI when a usable KDB is available, a bounded on-demand Slang Source Graph when NPI is unavailable or inconclusive, and Legacy Static as the final fallback. Results expose backend provenance, coverage, truncation, and fallback status rather than turning partial evidence into certainty.\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/gokeshenzhen/TraceWeave/main/assets/onepage-en.png\" alt=\"TraceWeave workflow overview\" width=\"900\">\n</p>\n\n<p align=\"center\"><sub>Default workflow and connectivity-routing overview; every conclusion remains bounded by reported coverage.</sub></p>\n\nTraceWeave is a workflow-oriented debug server rather than a loose collection of parsers. It combines:\n\n- A guided MCP workflow from artifact discovery through parallel hierarchy/structural analysis, failure parsing, runtime protocol scanning, and focused verification\n- Compile-evidence hierarchy construction, handle-based browsing, and source-aware structural analysis\n- VCD/FSDB point, transition, window, cycle, divergence, and period queries\n- Whole-design handshake scanning, targeted protocol checks, temporal predicates, and transaction reconstruction\n- Driver/load/path/X tracing through `trusted NPI -> bounded Source Graph -> Legacy Static`\n- Structured next actions plus coverage, provenance, truncation, and resource receipts designed for MCP clients\n\n[Architecture](https://github.com/gokeshenzhen/TraceWeave/blob/main/docs/architecture.md) · [Installation](#installation) · [Client Setup](#client-setup) · [Standard MCP Workflow](#standard-mcp-workflow) · [Tool Quick Reference](#tool-quick-reference) · [Testing](#testing) · [WeChat](#wechat)\n\n## When TraceWeave helps most\n\nTraceWeave adds the most value when debugging requires correlating evidence\nacross artifacts rather than reading one obvious RTL line. It is especially\nuseful for:\n\n- **Opaque runtime symptoms** such as timeouts, hangs, scoreboard mismatches,\n  X/Z propagation, first divergence, or a broken cadence. Waveform queries and\n  protocol/transaction analysis locate the first bad time, interface, or beat.\n- **Cross-hierarchy cause-and-effect questions** where a suspicious signal must\n  be followed through ports, interfaces, assignments, drivers, and consumers.\n- **Large or interface-rich designs** where whole-design handshake sweeps and\n  bounded hierarchy/Source Graph scopes reduce an otherwise open-ended search.\n- **Falsifiable hypothesis checks** that need a concrete witness or\n  counterexample from `verify_window`, divergence, period, handshake, or\n  reconstructed-transaction evidence.\n- **License-constrained environments** where Source Graph provides semantic\n  connectivity without NPI, while a usable KDB can still enable deeper local or\n  LSF-hosted Verdi NPI analysis.\n\nFor a small readable block with an obvious source-local logic error, direct\nsource and log inspection may be faster. TraceWeave also cannot reveal behavior\nabsent from every available source, log, waveform, and KDB artifact; with\nprotected IP it can follow only the evidence exposed at visible boundaries, in\nthe waveform, or in the elaborated database.\n\n## Architecture\n\n- Architecture map: `docs/architecture.md`\n- New-session bootstrap: read `AGENTS.md` first, then follow its first-read file list\n- Fast path for code understanding:\n  - `server.py`\n  - `config.py`\n  - `src/analyzer.py`\n  - `src/log_parser.py`\n  - `src/fsdb_parser.py`\n\n## Repository Layout\n\n```text\nTraceWeave/\n├── config.py                 # Environment-sensitive constants and discovery rules\n├── server.py                 # MCP entry point, session state, and workflow gating\n├── custom_patterns.yaml      # User-extensible log patterns\n├── fsdb_wrapper.cpp          # Native FSDB wrapper source\n├── build_wrapper.sh          # Builds libfsdb_wrapper.so\n├── scripts/                  # Full installer plus Source Graph / FSDB setup and verification\n├── tests/                    # Unit and integration tests\n└── src/\n    ├── path_discovery.py\n    ├── compile_log_parser.py\n    ├── tb_hierarchy_builder.py\n    ├── vcd_parser.py\n    ├── fsdb_parser.py\n    ├── fsdb_signal_index.py\n    ├── waveform_batch.py         # FSDB+VCD time-window batch reader\n    ├── log_parser.py\n    ├── analyzer.py\n    ├── signal_driver.py\n    ├── signal_load.py            # Load/fanout finder, Static + NPI\n    ├── connectivity_backend.py   # ConnectivityBackend protocol + select_backend\n    ├── verdi_backend.py          # KDB / license probe + kdb_hint generator\n    ├── verdi_npi_backend.py      # NPI-backed driver/load/path resolution\n    ├── npi_lsf.py                # Optional LSF transport + Verdi/NPI worker protocol\n    ├── npi_worker.py             # Compute-node Verdi/NPI worker entry point\n    ├── kdb_builder.py            # Auto-build Verdi KDB (vericom + elabcom) for Xcelium flows\n    ├── structural_scanner.py\n    ├── x_trace.py\n    ├── cycle_query.py\n    ├── schemas.py\n    ├── problem_hints.py\n    ├── hierarchy_provider.py     # Bounded lexical/semantic instance-binding views\n    ├── hierarchy_handles.py      # HandleStore + content-addressed handle for build_tb_hierarchy\n    ├── handle_tools.py           # get_tb_subtree / lookup_tb_files / find_tb_instance / ...\n    ├── cursor_store.py           # Named, process-scoped time anchors (cursor_set/list/delete)\n    ├── timespec.py               # Resolve @cursor / unit literals (12.34ns) to ps on time inputs\n    ├── verify_condition.py       # diff_first_divergence, period, inspect_handshake\n    ├── window_verify.py          # verify_window: temporal predicate over a clock window\n    ├── handshake_suggest.py      # suggest_handshakes / suggest_protocol_bundles\n    ├── handshake_sweep.py        # sweep_handshakes: whole-design handshake anomaly sweep\n    ├── txn_reconstruct.py        # reconstruct_transactions: id-correlated transaction layer\n    ├── cancellation.py           # Cooperative cancellation for worker-thread waveform scans\n    └── usage_telemetry.py        # Local-only per-call usage telemetry (default off; opt-in)\n```\n\n## Installation\n\nTraceWeave requires Python `3.11+`.\n\n### Choose an installation profile\n\nUse one installation profile from the start:\n\n| Profile | Intended use | Command |\n|---|---|---|\n| Repository-local full EDA | Simulation hosts with Source Graph, FSDB, Verdi/NPI, VCS/Xcelium, or LSF workflows | Clone this repository, then run `bash scripts/install.sh` |\n| Portable PyPI | Log/VCD analysis and the unlicensed Python fallback stack | `python -m pip install traceweave-mcp` |\n| Portable PyPI + Source Graph | Portable profile plus the pinned open-source `pyslang` frontend | `python -m pip install \"traceweave-mcp[source-graph]\"` |\n\nWhen a user gives an AI coding agent this repository URL and asks it to install\nTraceWeave, that means the **repository-local full EDA profile** unless the user\nexplicitly asks for the portable PyPI profile. Do not extend a PyPI environment\nwith repository FSDB setup scripts: the wheel and the repository resolve the\nnative wrapper from different runtime roots.\n\n### Repository-local full EDA installation\n\nThis is the recommended profile on simulation hosts and for users who have a\nlocal Verdi installation. It keeps Python packages, the FSDB wrapper, and the\nruntime links together under one repository root:\n\n```bash\ngit clone https://github.com/gokeshenzhen/TraceWeave.git\ncd TraceWeave\nexport VERDI_HOME=/path/to/verdi\nbash scripts/install.sh\n```\n\nAlternatively, pass the Verdi root for this installer process only:\n\n```bash\nbash scripts/install.sh --verdi-home /path/to/verdi\n```\n\nThe installer is a thin, idempotent orchestration of the established local\nworkflow:\n\n```text\nscripts/setup_source_graph.sh\n→ scripts/setup_fsdb.sh\n→ scripts/verify_fsdb.sh\n→ repository MCP runtime smoke check\n```\n\nIt never edits shell startup files or MCP client configuration. Inspect an\nexisting installation without creating an environment, compiling, or changing\nlinks:\n\n```bash\nbash scripts/install.sh --check\nbash scripts/install.sh --check --json\n```\n\nAfter a successful installation, print an absolute-path configuration template\nwithout writing it:\n\n```bash\nbash scripts/install.sh --print-config codex\nbash scripts/install.sh --print-config claude\nbash scripts/install.sh --print-config copilot\n```\n\nThe existing component commands remain supported for users and site automation\nthat already invoke them directly:\n\n```bash\nbash scripts/setup_source_graph.sh\nbash scripts/setup_fsdb.sh\nbash scripts/verify_fsdb.sh\n```\n\n`setup_source_graph.sh` installs `requirements-source-graph.txt` (the MCP\nruntime, PyYAML, and `pyslang==11.0.0`) into `.venv`. Its own read-only check is:\n\n```bash\nbash scripts/setup_source_graph.sh --check\n```\n\nFor FSDB support, the repository setup links\n`VERDI_HOME/share/FsdbReader/linux64/{libnsys.so,libnffr.so}` under\n`third_party/verdi_runtime/linux64` and builds `libfsdb_wrapper.so` in the\nrepository root. If those prerequisites are unavailable, use the portable\nprofile with VCD waveforms instead.\n\n> **After `git pull`**: `libfsdb_wrapper.so` is built locally, not tracked in\n> git. If a pulled update changed `fsdb_wrapper.cpp`, rebuild it with\n> `bash scripts/setup_fsdb.sh` (or `bash build_wrapper.sh`) and rerun\n> `bash scripts/verify_fsdb.sh`. An outdated ABI deliberately fails loudly\n> rather than risking misaligned waveform timestamps.\n\nFor a legacy repo-local minimal installation without Source Graph, the existing\nmanual dependency setup remains available:\n\n```bash\npython3.11 -m pip install \"mcp==1.27.0\" pyyaml --user\n```\n\n### Portable PyPI installation\n\nInstall the base MCP runtime and launch the stdio server from any directory:\n\n```bash\npython -m pip install traceweave-mcp\ntraceweave-mcp\n```\n\nThe base package includes log/VCD analysis and the unlicensed Python fallback\nstack. To add the pinned open-source Source Graph frontend:\n\n```bash\npython -m pip install \"traceweave-mcp[source-graph]\"\n```\n\n`pyslang` is intentionally optional: the server starts without it and reports a\nstructured Source Graph dependency blocker before falling back to Legacy\nStatic. Inspect this installation without starting the stdio server:\n\n```bash\ntraceweave-mcp --doctor\ntraceweave-mcp --doctor --json\n```\n\nPyPI distributions do not contain `fsdb_wrapper.cpp`, `build_wrapper.sh`, the\nrepository FSDB setup scripts, `libfsdb_wrapper.so`, Synopsys/Cadence runtime\nlibraries, license data, VCS/Xcelium, or the proprietary Verdi `pynpi` runtime.\nSetting `VERDI_HOME` can provide external EDA libraries, but it does not create\nthe missing TraceWeave FSDB wrapper. A manually injected wrapper inside\n`site-packages` is an unsupported mixed layout; use the repository-local full\nEDA profile instead. Verdi NPI discovery is independent of the FSDB reader and\nremains conditional on the site's complete KDB, `pynpi`, runtime, license, and\nlocal/LSF environment.\n\nThe Official MCP Registry distribution uses the name\n[`io.github.gokeshenzhen/traceweave`](https://registry.modelcontextprotocol.io/).\nAfter publication, use that exact name or `traceweave` in the registry search\nbox.\n\n## Client Setup\n\n### Generic MCP Client\n\nAny MCP client that supports stdio transport can connect to this server. The minimum configuration is:\n\n- Portable PyPI installation: command `traceweave-mcp`, args `[]`\n- Repository-local full EDA installation: command `<TRACEWEAVE_HOME>/.venv/bin/python` after running `scripts/install.sh`, args `[\"<TRACEWEAVE_HOME>/server.py\"]`\n- EDA env: keep the site-provided Verdi/NPI, VCS/Xcelium, license, and optional LSF variables available to the repository-local MCP process\n\nIf the client supports server instructions, it can follow the built-in workflow directly. Otherwise, use the workflow below.\n\n### Claude Code\n\nEnvironment inheritance depends on how the MCP client itself is launched and on\nthat client's environment policy. In one tested terminal-launched `tcsh`/LSF\nsetup, Claude Code passed the shell-configured LSF, Verdi, and license variables\nto TraceWeave, and remote NPI driver/load/path queries worked without a separate\nMCP environment list. An IDE/GUI launch or another client setup may not inherit\nthe same environment. For a deterministic Claude Code setup, list every variable\nthe server needs — tool roots plus the `dlopen` chain (`LD_LIBRARY_PATH` is the\none most often missed; without it NPI silently falls back to Static and\n`trace_signal_path` returns `found: false`).\n\nAdd this to `~/.claude.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"TraceWeave\": {\n      \"command\": \"<TRACEWEAVE_HOME>/.venv/bin/python\",\n      \"args\": [\"<TRACEWEAVE_HOME>/server.py\"],\n      \"env\": {\n        \"VERDI_HOME\": \"<verdi-install>\",\n        \"NOVAS_HOME\": \"<verdi-install>\",\n        \"VCS_HOME\": \"<vcs-install>\",\n        \"XLM_ROOT\": \"<xcelium-install>\",\n        \"CDS_INST_DIR\": \"<xcelium-install>\",\n        \"SNPSLMD_LICENSE_FILE\": \"xxxx@s-license.example.com\",\n        \"LM_LICENSE_FILE\": \"xxxx@s-license-server.example.com\",\n        \"CDS_LICENSE_FILE\": \"xxxx@c-license.example.com\",\n        \"LD_LIBRARY_PATH\": \"<library-path>\",\n        \"PATH\": \"<path>\"\n      }\n    }\n  }\n}\n```\n\nVerify the connection:\n\n```bash\nclaude mcp list\n# Should show TraceWeave (connected)\n```\n\n### Codex\n\nCodex supports two ways to provide environment variables to the TraceWeave MCP\nserver:\n\n- Put fixed values in `[mcp_servers.TraceWeave.env]`. This suits stable tool and\n  license locations, or a Codex process that is not launched from a configured\n  terminal.\n- Use `env_vars` to allow and forward variables already inherited by the Codex\n  process. This suits EDA environments managed by `.bashrc`, `.tcshrc`, or a\n  site setup script.\n\nChoose one source for each variable; do not configure the same name in both\n`env` and `env_vars`. This matches the official\n[Codex MCP configuration](https://developers.openai.com/codex/mcp/). The example\nbelow uses fixed values in `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.TraceWeave]\ncommand = \"<TRACEWEAVE_HOME>/.venv/bin/python\"\nargs = [\"<TRACEWEAVE_HOME>/server.py\"]\ncwd = \"<TRACEWEAVE_HOME>\"\n\n[mcp_servers.TraceWeave.env]\nVERDI_HOME = \"<verdi-install>\"\nNOVAS_HOME = \"<verdi-install>\"\nVCS_HOME = \"<vcs-install>\"\nXLM_ROOT = \"<xcelium-install>\"\nCDS_INST_DIR = \"<xcelium-install>\"\nSNPSLMD_LICENSE_FILE = \"xxxx@s-license.example.com\"\nLM_LICENSE_FILE = \"xxxx@s-license-server.example.com\"\nCDS_LICENSE_FILE = \"xxxx@c-license.example.com\"\nLD_LIBRARY_PATH = \"<library-path>\"\nPATH = \"<path>\"\n```\n\nIf a site setup script manages these values, do not copy its expanded values\ninto `env`. Launch Codex from the configured terminal and use the inherited\nenvironment pattern in the LSF-only section below instead.\n\nVerify the connection:\n\n```bash\ncodex mcp list\n# Should show TraceWeave with Status: enabled\n```\n\n### LSF-only NPI licenses\n\nSome EDA sites grant Verdi/NPI licenses only to scheduled compute nodes. NPI\nexecution remains local by default; opt in to LSF at the **TraceWeave MCP\nserver process** with:\n\n```bash\nexport TRACEWEAVE_NPI_EXECUTION=lsf\nexport TRACEWEAVE_NPI_LSF_QUEUE=\"digital\"\n```\n\nHere `digital` is only an example; replace it with the user's licensed team\nqueue. TraceWeave reads only the namespaced `TRACEWEAVE_NPI_LSF_QUEUE`; it does\nnot create, overwrite, or interpret a site's generic `LSF_QUEUE`. If the site\nalready exports `LSF_QUEUE`, the user may map that existing value instead:\n\n```bash\nexport TRACEWEAVE_NPI_LSF_QUEUE=\"$LSF_QUEUE\"\n```\n\nFor `tcsh`:\n\n```tcsh\nsetenv TRACEWEAVE_NPI_EXECUTION lsf\nsetenv TRACEWEAVE_NPI_LSF_QUEUE \"digital\"\n```\n\nOr, only when `LSF_QUEUE` already exists:\n\n```tcsh\nsetenv TRACEWEAVE_NPI_LSF_QUEUE \"$LSF_QUEUE\"\n```\n\nPutting these values in `.bashrc` / `.tcshrc` works only when the MCP client\npasses that shell environment to the TraceWeave server. In the tested\nterminal-launched setup, Claude Code did so and completed LSF-hosted NPI\ndriver/load/path queries. Codex required the needed site variables to be named\nin `env_vars`; without them, the NPI attempt failed.\n\nThe following Codex configuration is for an EDA environment already established\nby the parent shell. It is an alternative to the fixed-value EDA block in the\nCodex section above. The list reflects one tested LSF/EGO site; add or remove\nnames to match the site's setup, and do not repeat any name under `env`:\n\n```toml\n[mcp_servers.TraceWeave]\ncommand = \"<TRACEWEAVE_HOME>/.venv/bin/python\"\nargs = [\"<TRACEWEAVE_HOME>/server.py\"]\ncwd = \"<TRACEWEAVE_HOME>\"\nenv_vars = [\n  \"TRACEWEAVE_NPI_LSF_QUEUE\",\n\n  \"LSF_ENVDIR\",\n  \"LSF_BINDIR\",\n  \"LSF_SERVERDIR\",\n  \"LSF_LIBDIR\",\n  \"PATH\",\n\n  \"EGO_TOP\",\n  \"EGO_BINDIR\",\n  \"EGO_CONFDIR\",\n  \"EGO_ESRVDIR\",\n  \"EGO_LIBDIR\",\n  \"EGO_LOCAL_CONFDIR\",\n  \"EGO_SERVERDIR\",\n\n  \"VERDI_HOME\",\n  \"LD_LIBRARY_PATH\",\n\n  \"LM_LICENSE_FILE\",\n  \"SNPSLMD_LICENSE_FILE\",\n]\n\n[mcp_servers.TraceWeave.env]\nTRACEWEAVE_NPI_EXECUTION = \"lsf\"\n```\n\nValues under `[mcp_servers.TraceWeave.env]` are copied literally by Codex, so do not write\n`TRACEWEAVE_NPI_LSF_QUEUE = \"$LSF_QUEUE\"` there. `env_vars` is the supported\nway to forward the value that the user's shell already expanded. If the Codex\nparent does not inherit the shell environment, omit the queue from `env_vars`\nand put a fixed `TRACEWEAVE_NPI_LSF_QUEUE = \"digital\"` directly under\n`[mcp_servers.TraceWeave.env]` instead. If some EDA values are intentionally\nfixed under `env`, omit those same names from `env_vars`.\n\nIn the tested terminal-launched Claude Code setup, no extra MCP environment map\nwas needed when the shell already exported both namespaced values and the full\nsite environment. For a deterministic setup, or when the client does not inherit\nthat shell, merge the following fixed values into the existing TraceWeave\nserver's `\"env\"` object (replace `digital` with the user's queue):\n\n```json\n{\n  \"TRACEWEAVE_NPI_EXECUTION\": \"lsf\",\n  \"TRACEWEAVE_NPI_LSF_QUEUE\": \"digital\"\n}\n```\n\nJSON values are literal too; do not put `\"$LSF_QUEUE\"` in this static map.\n\nWith this mode enabled, explicit connectivity operations\n(`explain_signal_driver`, `find_signal_loads`, `trace_signal_path`,\n`trace_x_source`) and every `build_kdb` cache miss or forced rebuild submit a\nshort `bsub -K` worker. Exact KDB cache hits, log parsing, waveform reads,\nstructural scans, KDB detection, and Static analysis remain local because they\ndo not invoke a licensed Verdi executable. Connectivity-worker failure or\ntimeout falls through to the local Source Graph and then to Legacy Static if\nthat bounded graph is unavailable or inconclusive. A KDB-build worker failure\ndoes **not** fall back to local `vericom`/`elabcom`; `build_kdb` returns a fixed\nfailure receipt instead. Static still has no\npath API, so a final path fallback is explicitly unsupported. Routing is visible through fixed\n`backend_status.execution_mode` / `scheduler_status` / `worker_status` /\n`fallback_reason` labels; queue, host, command, and license details are not\nreturned.\n\nAfter restarting or reconnecting the MCP server, ask the AI agent to run one\nexplicit connectivity operation and report `backend_status`. A successful LSF\nNPI call has `execution_mode=\"lsf\"`, `scheduler_status=\"completed\"`,\n`worker_status=\"completed\"`, and `actual_backend=\"verdi_npi\"`. Otherwise inspect\n`fallback_reason`; a Static fallback is not an exact NPI result.\n\nFor an Xcelium KDB cache miss, `build_kdb` exposes the same top-level\n`execution_mode` / `scheduler_status` / `worker_status` / `fallback_reason`\nlabels. A successful remote build reports `execution_mode=\"lsf\"` and both\nstatuses as `\"completed\"`; a cache hit reports both statuses as\n`\"not_started\"` because no license-bearing process ran.\n\nAn error-marked KDB may still complete the worker successfully. In that case\n`actual_backend=\"verdi_npi\"` is paired with `kdb_degraded=true`; read the NPI\nattempt's `coverage_status=\"partial\"` and the `kdb_error_count` /\n`kdb_error_log` diagnostics rather than treating scheduler completion alone as\nproof of complete elaboration.\n\nOptional settings:\n\n```bash\nexport TRACEWEAVE_NPI_LSF_TIMEOUT=120\nexport TRACEWEAVE_NPI_LSF_KDB_TIMEOUT=1260\nexport TRACEWEAVE_NPI_LSF_BSUB=/path/to/bsub\nexport TRACEWEAVE_NPI_LSF_BKILL=/path/to/bkill\nexport TRACEWEAVE_NPI_LSF_PYTHON=/path/to/python3.11\nexport TRACEWEAVE_NPI_LSF_STAGING_DIR=/shared/private/traceweave-npi\nexport TRACEWEAVE_NPI_LSF_EXTRA_ARGS_JSON='[\"-R\", \"select[...]\"]'\n```\n\nThe compile log, every source/include input, TraceWeave checkout/installation,\nstaging directory, and `TRACEWEAVE_CACHE_DIR` (including the generated KDB)\nmust be visible at the same absolute paths on the submission and compute nodes.\nAfter a remote success the parent verifies that the returned KDB path is\nvisible; otherwise it reports `npi_lsf_artifact_unavailable`. The staging\ndirectory defaults under TraceWeave's cache root; set it explicitly when that\ncache is not on a shared filesystem. `TRACEWEAVE_NPI_LSF_TIMEOUT` controls\nshort connectivity jobs; `TRACEWEAVE_NPI_LSF_KDB_TIMEOUT` separately bounds\nqueue wait plus both KDB phases (default 1260 seconds). Scheduler options are\nJSON argv, not shell text, and are limited to scheduler option/value pairs.\n\n### On-Demand Source Graph\n\n`explain_signal_driver`, `find_signal_loads`, `trace_signal_path`, and\n`trace_x_source` use the production route\n`Verdi NPI -> Source Graph -> Legacy Static`. Source Graph is lazy and\nprocess-local: the first eligible request starts one isolated, short-lived\nfrontend worker, successful scoped IR enters the server's bounded memory cache,\nand same-key cold requests share one build. Artifact identity is independent of\nthe query target; QueryIdentity remains target-specific. By default it neither\nbuilds nor scans a cache at startup, does not use disk persistence, does not hold\nan FSDB/VCD lock, and does not import `pyslang` into the MCP server.\n\nFor `trace_x_source`, a trusted NPI result remains authoritative. An internal\nNPI fallback discards the partial propagation chain and restarts from the root\nwith one bounded Source Graph artifact. Multiple driver targets inside its\nproved scope reuse that artifact. If a new X-bearing target requires a larger\nscope, only the exact hierarchy ancestor union is added and the Source Graph\ntrace restarts; facts from the smaller artifact are discarded. Build/query\nfailure, an unsafe scope explanation, or a coverage-incomplete negative causes\na whole-trace Static restart. Cancellation never advances the fallback chain.\n\nFor a path request, the adapter proves both hierarchy ancestor chains share one\ntop and projects only their ancestor union through the lowest common ancestor;\nit does not enumerate unrelated siblings or the full design. The query returns a\ndeterministic shortest-hop structural path over supported IR bindings and\ncombinational dependencies. The BFS queue stores one selection plus one\npredecessor hop per first-discovered state, then reconstructs the selected path\nonce; it never duplicates every complete path prefix across the frontier. A\npartial positive remains partial. Only a coverage-complete negative is\n`not_connected`; inconclusive or truncated negatives continue to Static's\nstructured unsupported result. `expand_assigns` only exposes real IR/source\nassignment evidence and does not change whether the endpoints are connected.\n\nWhile `build_tb_hierarchy` reads sources and resolved includes, it captures a\nprivate immutable compile-session snapshot containing only content digests,\nstat identities, byte counts, and fixed-label semantic markers--never source\ntext. When the default parallel `build_tb_hierarchy` and\n`scan_structural_risks` calls overlap on the same compile identity, a transient\nsingle-flight index lets both consume text and exact digest/stat/marker facts\nfrom one physical read. It is bounded, process-memory only, and clears all\nsource bodies as soon as the final active call releases it; hierarchy handles\nand results retain only compact facts. The first Source Graph request reuses\nevery still-current record instead of reopening that file, reported as\n`fingerprint_cache_disposition=miss_reused_compile_session`; support inputs not\nseen by hierarchy are still read and hashed normally. This includes\nsimulator/frontend replay-only tool-library inputs (for example `uvm_pkg.sv`\nexpanded from VCS `-ntb_opts uvm`), which are not project hierarchy evidence.\nEvery original project input must still have a current snapshot record. Later\nrequests reuse the bounded in-memory manifest as `hit_session_snapshot`. Every\nreused record is stat-validated, and a changed source blocks the stale\nhierarchy/manifest pair with `compile_session_snapshot_changed`; rebuild and\nrefresh the hierarchy before querying. A changed compile log or refreshed\nhierarchy handle likewise invalidates the snapshot.\n\nFor a large, complete Verilog/SystemVerilog manifest, the adapter can derive a\ncompile-input closure from the hierarchy scan facts already held by that\nhandle: the proved ancestor definitions, explicit compile tops/bind tops,\npackage imports and qualified package references, and compile-order macro\ndefinitions/undefinitions. Slang remains the parser and elaborator; this\nplanner is not a replacement compiler. The full ordered manifest and content\nfingerprint remain the artifact's invalidation identity, while only the\nordered closure is sent to the isolated worker and only the requested design\ntop is elaborated. Missing or ambiguous proof, incomplete/mixed-language\ninputs, duplicate inputs, or a closure that is too large safely retains the\nfull replay. Adapter receipts expose only fixed-label/count telemetry under\n`manifest.compile_projection`. Every applied closure adds\n`compile_projection_pruned_inputs`, so its graph is explicitly\n`inconclusive`: IR-proved positive driver/load/path facts remain usable, but an\nempty result can never establish `no_driver`, `no_load`, or `not_connected`.\n\nFor a deep recursive driver query, or a load query with an explicit depth above\none, the first large-manifest projection may include the target leaf's adjacent\nsiblings instead of waiting for a failed narrow query and rebuilding. This is a\nbounded admission policy, not a general subtree expansion: the parent and every\ndirect child must be proved by the hierarchy; at most 32 new instances and 24\nadditional closure inputs are admitted; and a base closure of at least 32 inputs\nmay grow by no more than 25%. The existing\n`TRACEWEAVE_SOURCE_GRAPH_FRONTIER_MAX_INSTANCES` cap also applies. Shallow\nqueries, full-manifest replay, bounded bootstrap, unresolved hierarchy, or any\ncostlier shape keeps the exact ancestor artifact. If runtime evidence still\nrequires another frontier, the proactively admitted parent is retained in the\nnext exact ancestor union, so no scope or fact from two artifacts is mixed.\nThis changes only preparation scheduling: coverage exclusions, fingerprints,\nsingle-artifact provenance, public inputs, and result schemas are unchanged.\n\nRepeated deep queries below one proved parent can optionally reuse a bounded\nSlang semantic session while still publishing a separate narrow IR for each\nscope. This accelerator is guarded and disabled by default:\n\n```bash\nexport TRACEWEAVE_SOURCE_GRAPH_SEMANTIC_SESSION=1\nexport TRACEWEAVE_SOURCE_GRAPH_SEMANTIC_SESSION_IDLE_TTL=60\nexport TRACEWEAVE_SOURCE_GRAPH_SEMANTIC_SESSION_MAX_RSS_BYTES=805306368\nexport TRACEWEAVE_SOURCE_GRAPH_SEMANTIC_SESSION_MAX_INSTANCES=64\nexport TRACEWEAVE_SOURCE_GRAPH_SEMANTIC_SESSION_MAX_INPUTS=256\n```\n\nThe adapter keeps the artifact narrow and binds it to a separately proved\nparent context within the instance/input caps. One isolated child retains at\nmost one exact source/options/top/snapshot context; a second eligible scope\nprojects from that root without reparsing. A context change restarts the child,\n60 seconds of inactivity evicts it, and cancellation, timeout, crash, protocol\nfailure, or either live/reported RSS limit breach destroys the whole session\nwithout publishing a partial artifact. A frontier outside the retained context\nuses the historical one-shot worker and leaves the parent session available.\nOnly compact scoped IR enters memory or the optional disk cache; Slang state\nnever enters the MCP process or disk. Additive numeric receipts report session\nhits, misses, restarts, evictions, and frontend launches. Requests that lack a\ncomplete bounded context retain the default one-shot behavior.\n\nUse `scripts/soak_source_graph_semantic_session.py` before changing that\ndefault. It accepts an external list of 20--100 unique exact deep driver/load\nqueries and compares the current one-shot lifecycle with the production\npersistent runner in two fresh processes. The aggregate-only report checks\nfact/status/coverage equivalence, launch and reuse counts, sequence and first-\nquery latency, break-even ordinal, tail latency, RSS cap/growth, failures, and\nevictions. A passing single-design run still sets `default_on_authorized=false`;\nrepresentative eligible designs and real query-frequency evidence are required\nto justify retaining the frontend process. If bounded adjacent expansion\nalready produces one reusable compact artifact, the workload is reported as\n`not_needed_existing_artifact_scope` instead of counting memory-cache hits as\nsemantic-session hits. Run the script with `--help` for its full invocation.\n\nVCS flows that split source compilation and elaboration across logs can build\none context explicitly. Keep the source-compile log as the primary path (and\nuse it for the structural scan), then supply the other source/elaboration logs\nin their build order:\n\n```text\nbuild_tb_hierarchy(\n  compile_log=\".../comp.log\",\n  supplementary_compile_logs=[\".../vhdl_comp.log\", \".../elab.log\"],\n  simulator=\"vcs\",\n)\n```\n\nThe resulting handle, hierarchy snapshot, and Source Graph compile fingerprint\ncover every log and every ordered source/support input. Connectivity tools keep\ntheir existing signatures and continue to receive the same primary\n`compile_log`. Conflicting simulators/tops, duplicate logs, incomplete source\norder, or material parse warnings keep the manifest conservative instead of\ninventing a combined command.\n\n#### Large compile sets and bounded bootstrap\n\nFull hierarchy construction remains the default because it is the testbench\npanorama used by hierarchy browsing and whole-design analysis. Compile logs are\nnow parsed as streams, and the handle retains compact per-file facts rather than\nraw source bodies. The slim result includes numeric `build_metrics`, including\nsource counts/bytes, phase timings, RSS samples, `source_text_bytes_retained=0`,\nprivacy-safe compile-session snapshot counts/bytes/completeness, and bounded\npreprocessor/source-index counters. `scan_structural_risks` exposes the same\nprivacy-safe source-index facts under `scan_metrics`. Those counters distinguish physical source loads,\nsource/masked-text cache hits and bytes, logical expansions, comment-mask fast\npaths, plain expansion-line fast paths, and exact/LRU include-resolution hits,\nmisses, entries, and evictions; they never expose paths, include names, macros,\nor source content. Source Graph manifest receipts expose digest reuse/read\ncounts and bytes plus a conflict count under the same privacy boundary.\n\nRepeated module/UVM descendants are retained as an internal template object\nDAG while preserving the existing nested-dict hierarchy and handle-tool\nschemas. Logical stats count each instance path, but memoized summaries and the\nretained handle do not copy an identical descendant subtree for every parent.\nThe metrics report logical nodes, reachable physical nodes, allocations, cache\nhits, and reused nodes. If local NPI later adds instance-specific `file:line`\nfacts, the overlay uses copy-on-write only along annotated paths, so siblings\nsharing one template cannot acquire each other's provenance.\n\nHierarchy edges are positive evidence, not an elaboration guess. Full-build\nscan records and admitted nodes carry fixed origin/status/gap metadata. Explicit\nor implicit generate controls, instance arrays, and bind statements remain raw\ndiagnostic candidates but are not flattened into fictitious child paths;\nduplicate definitions stop at an ambiguous node without guessed descendants.\nParameter overrides keep their safe direct edge while recording that the public\ncompatibility tree did not materialize the specialization. Source Graph carries\nquery-relevant hierarchy gaps into its receipt and coverage boundary, preventing\ncomplete negative claims; the parameter-only gap is informational because Slang\nperforms specialization itself. Build metrics include candidate/unresolved and\nduplicate-definition counts using only numeric values and fixed labels.\n\nInternally, Source Graph no longer depends directly on the compatibility tree\nshape. `hierarchy_provider.py` defines bounded O(depth) scope lookup, exact\ninstance-to-definition bindings, and capped direct-child reads. The default\ncompile-log provider wraps `component_tree` without importing Slang. Every\nprepared Connectivity IR exposes a second semantic provider over its existing\nquery-engine indexes, so generate-scope paths, instance arrays, and parameter\nspecializations retain their elaborated `InstanceDecl` bindings without\ncopying another full hierarchy or rebuilding path dictionaries. Provider-local\nstable instance IDs are scoped by the immutable design identity; the public\nhierarchy and Source Graph receipt schemas are unchanged.\n\nFor offline provider validation on a licensed development host,\n`scripts/benchmark_hierarchy_provider_soc.py` compares this Slang provider with\na bounded NPI oracle in separate fresh processes. The NPI arm performs only\nexact dotted-prefix `get_inst()` lookups (256 by default, hard-capped at 1,024),\nnever a top/sibling walk, and its partial fragment cannot support exhaustive\nnegative hierarchy claims. The benchmark emits hashes, counts, timings, and RSS\nrather than signal/source/instance names. It is opt-in development tooling: it\ndoes not run from `build_tb_hierarchy` and does not change production backend\nrouting.\n\nThe companion `scripts/benchmark_connectivity_differential_soc.py` compares a\nbounded driver/load/path corpus against direct NPI and Source Graph execution.\nEach provider runs in a fresh process, and neither arm may enter the production\nfallback chain. The Source Graph arm prepares exactly one bounded artifact per\nquery attempt; an incomplete projection remains an explicit coverage fact\nrather than being hidden by dynamic expansion or Static output. Reports omit\nquery text, signal/scope/source paths, and expressions. They contain only\nSHA-256 evidence anchors, counts, fixed statuses, timings, cache metrics, and\nRSS; driver/load rows also retain their numeric, fixed-label resource-bound\nreceipt so truncation is measurable without exposing design identity. NPI-only\nfacts are classified as coverage-explained while Source Graph is\nnon-exhaustive and as unexpected only under exhaustive Source Graph coverage;\nSource Graph-only facts and path reachability differences remain separate\ncategories because NPI is a reference, not an infallible oracle.\n\nThe input is a bounded JSON corpus (at most 64 semantic queries):\n\n```json\n{\n  \"schema_version\": \"1.0\",\n  \"queries\": [\n    {\"operation\": \"driver\", \"signal_path\": \"tb.dut.result\", \"recursive\": true},\n    {\"operation\": \"loads\", \"signal_path\": \"tb.dut.request\", \"max_depth\": 1},\n    {\"operation\": \"path\", \"from_signal\": \"tb.dut.a\", \"to_signal\": \"tb.dut.b\"}\n  ]\n}\n```\n\nRun it only on an authorized licensed development host:\n\n```bash\npython3.11 scripts/benchmark_connectivity_differential_soc.py \\\n  --compile-log <compile.log> --corpus <queries.json> --top <top>\n```\n\nThis benchmark is development tooling only. It is not called by an MCP tool\nand does not select, promote, or suppress a production backend.\n\nThe full scanner avoids repeated work without weakening preprocessing proof.\nSlash-free lines outside a block comment bypass the character masker; quoted\nstrings are removed with the same grammar before structural token collection;\nand simulator-recorded include edges provide an unambiguous basename index\nbefore directory search. Positive include resolutions then enter a 4,096-entry\nLRU, while unresolved includes are never cached. Definition regexes accept only\nhorizontal indentation, so `^\\s*` cannot backtrack across thousands of blank\nlines in expanded headers. Within a directive-bearing compilation unit, an\nactive comment-aware line with no backtick bypasses both directive and hierarchy\nmacro recognition. Metadata regexes run only when their required literal is\npresent, and an expanded/trusted structural view replaces root-local instance\nfacts without first parsing and discarding that root instance list. Ambiguous\ninclude basenames retain ordered include-directory resolution, and all\noptimizations preserve per-compilation-unit macro state, cancellation\ncheckpoints, compact snapshots, and the public hierarchy schema.\n\nTwo optional full-build guardrails are disabled by default. Set them below an\nouter MCP watchdog when a site wants a structured blocker instead of an opaque\nclient/process termination:\n\n```bash\nexport TRACEWEAVE_HIERARCHY_TIMEOUT=20\nexport TRACEWEAVE_HIERARCHY_MAX_SOURCE_BYTES=1073741824\n```\n\nThe transient shared-source tier is enabled by default and has independent\nlimits. A capacity miss safely uses the original readers; it does not block the\ntools or publish a partial hierarchy:\n\n```bash\nexport TRACEWEAVE_COMPILE_SOURCE_INDEX=1\nexport TRACEWEAVE_COMPILE_SOURCE_INDEX_MAX_BYTES=134217728\nexport TRACEWEAVE_COMPILE_SOURCE_INDEX_MAX_FILES=32768\n```\n\nSet `TRACEWEAVE_COMPILE_SOURCE_INDEX=0` to disable sharing. Invalid or\nnon-positive limits disable only the optimization and appear as the fixed\n`compile_source_index_config_invalid` disposition.\n\nA guardrail hit returns `build_status=\"blocked\"`, a fixed `blocker`, and no\n`hierarchy_handle`; it does not masquerade as a partial panorama. The compact\ncompile context is retained in a four-entry process cache so a subsequent\nsingle-endpoint driver/load query can opt into bounded bootstrap:\n\n```text\nfind_signal_loads(\n  signal_path=\"top.u_agent.gate_en\",\n  compile_log=\".../comp.log\",\n  supplementary_compile_logs=[\".../elab.log\"],\n  simulator=\"vcs\",\n  allow_bounded_bootstrap=true,\n)\n```\n\nBootstrap is intentionally not a replacement for `build_tb_hierarchy`. It is\navailable only for `explain_signal_driver` and `find_signal_loads`, keeps NPI\nprecedence, searches only simulator-recorded ordered inputs (never the\nfilesystem), proves the top-to-target instance chain plus package/include and\npreprocessor context, fingerprints every selected input, and removes broad\n`-v`/`-y` library search options from bootstrap replay. A `uvm_pkg` import is\nkept as the explicit `uvm_dynamic_connectivity` exclusion without expanding the\nwhole simulator UVM library. A proved positive\nSource Graph fact is usable but remains scoped: `coverage_status` is\n`inconclusive`, `exhaustive_search=false`, and `negative_claim_allowed=false`.\nWhen preprocessing is imperfect, the receipt exposes only fixed, privacy-safe\n`preprocessor_issue_categories`. A target chain entirely proved before an\nuncertainty boundary may continue with\n`bootstrap_include_context_incomplete`; if the unresolved context could hide a\nremaining instance segment, bootstrap stops with\n`bootstrap_include_context_unproved`. No path, macro value, or source fragment\nis added to the public diagnostic. A direct generate/array/bind candidate is\nalso never promoted into a flat ancestor chain: bootstrap stops with\n`bootstrap_hierarchy_edge_unproved` and a fixed hierarchy coverage exclusion.\nIf an exact full-design source index is already active, bootstrap may reuse it;\non a miss it reports `miss_no_active_session` and keeps its original bounded\nreader instead of initiating a full-project preload.\nIf proof, build, or query is inconclusive, the bootstrap route returns an honest\nno-fact receipt and does not launch the whole-source Legacy Static scan that it\nwas introduced to avoid. The normal full-hierarchy route keeps its existing\nSource Graph-to-Static fallback.\n\nBootstrap limits are hard and independently configurable (byte values are plain\nintegers). The defaults leave substantial headroom above the reported\n3,843-source workload. The 24-second internal timeout deliberately remains\nbelow its observed 27-second outer termination so TraceWeave can return a\nstructured blocker instead of being cut off mid-request:\n\n```bash\nexport TRACEWEAVE_BOOTSTRAP_TIMEOUT=24\nexport TRACEWEAVE_BOOTSTRAP_MAX_SOURCE_INPUTS=128\nexport TRACEWEAVE_BOOTSTRAP_MAX_SOURCE_BYTES=67108864\nexport TRACEWEAVE_BOOTSTRAP_MAX_INVENTORY_FILES=16384\nexport TRACEWEAVE_BOOTSTRAP_MAX_INVENTORY_BYTES=1073741824\nexport TRACEWEAVE_BOOTSTRAP_MAX_INCLUDE_DEPTH=64\nexport TRACEWEAVE_BOOTSTRAP_MAX_HIERARCHY_DEPTH=256\n```\n\nRun the reproducible reported-scale benchmark with:\n\n```bash\npython3.11 scripts/benchmark_hierarchy_bootstrap.py --mode hierarchy\npython3.11 scripts/benchmark_hierarchy_bootstrap.py --mode bootstrap\n```\n\nFor the same before/after measurement on a real compile log, use the\ncompile-log-only benchmark below. It disables the optional NPI source overlay\nby default, omits paths from its output, and reports the structural result hash,\nhierarchy counts, phase timing, RSS, and preprocessor counters. Repeat\n`--supplementary-compile-log` for split compile/elaboration flows; use\n`--npi-source-overlay` only when that separately licensed overlay is the target\nof the measurement.\n\n```bash\npython3.11 scripts/benchmark_tb_hierarchy.py \\\n  --compile-log /path/to/build.log --simulator vcs\n```\n\nPass `--no-hierarchy-template-sharing` only for a real-design eager/shared A/B.\nThe focused fresh-process synthetic benchmark makes repeated-subtree scaling\nand semantic equivalence directly reproducible:\n\n```bash\npython3.11 scripts/benchmark_hierarchy_materialization.py \\\n  --branches 1000 --fanout 1000 --repeats 3\n```\n\nUse the companion structural benchmark to measure the other half of the\ndefault parallel source-analysis step. It reports no paths or finding text;\ninstead it emits wall/RSS, logical source opens and bytes, per-category counts,\nand a hash of the complete result for before/after equivalence checks.\n\n```bash\npython3.11 scripts/benchmark_structural_scan.py \\\n  --compile-log /path/to/build.log --simulator vcs\n```\n\nTo measure the shared tier itself, the combined benchmark runs both public\ntools in parallel in fresh processes, alternates enabled/disabled trial order,\nand reports read amplification, wall/RSS, and both complete semantic hashes:\n\n```bash\npython3.11 scripts/benchmark_compile_source_index.py \\\n  --compile-log /path/to/build.log --simulator vcs --repeats 3\n```\n\nMixed Verilog/SystemVerilog/VHDL builds remain eligible when the selected top\nand queried region can be elaborated by the Verilog/SystemVerilog frontend.\nCompile-command and filelist inputs use one shared, case-insensitive suffix\npolicy: `.v`, `.vh`, `.sv`, `.svh`, `.svi`, `.sva`, and `.svl` are regular\nfrontend text inputs. `.svp` is retained in exact order, content fingerprints,\nworker requests, and KDB build inputs, but is treated as protected: lexical\nhierarchy/risk scans do not inspect its payload and Source Graph coverage\nreports `protected_region` rather than claiming visibility into encrypted IP.\nVHDL files stay in the content identity but are not passed to Slang; coverage\nreports `opaque_vhdl_boundary` (and the unprojected-file count). A frontend\ndiagnostic or opaque VHDL region therefore prevents exhaustive negative claims,\nbut does not discard proved positive driver/load/path facts: a query with a\npositive fact returns Source Graph with `positive_fact_confidence`, while only\nan inconclusive no-match advances to Legacy Static. VHDL internals and a design\nwhose selected elaboration top is itself VHDL are not projected in this phase.\n\nSource Graph is enabled by default. If the MCP interpreter does not have the\noptional frontend, the dependency blocker is recorded and the request continues\nto Legacy Static. The recommended setup installs `pyslang==11.0.0` into the\nsame repository-local interpreter used to launch the MCP server:\n\n```bash\nbash scripts/setup_source_graph.sh\n# Configure the MCP command as <TRACEWEAVE_HOME>/.venv/bin/python\n```\n\nNo Source Graph-specific environment variable is required on that path: the\ndefault policy is enabled, expects frontend version `11.0.0`, and launches its\nisolated worker with the MCP interpreter. Sites that deliberately keep the\nnative frontend in a separate pinned Python environment can instead configure:\n\n```bash\nexport TRACEWEAVE_SOURCE_GRAPH=1\nexport TRACEWEAVE_SOURCE_GRAPH_PYTHON=/path/to/pyslang-11.0.0/bin/python\nexport TRACEWEAVE_SOURCE_GRAPH_FRONTEND_VERSION=11.0.0\nexport TRACEWEAVE_SOURCE_GRAPH_TIMEOUT=120\n```\n\nIf a site compile wrapper adds a private plusarg that is known to be strictly\nruntime-only, it can be excluded from frontend replay with an exact local\nallowlist:\n\n```bash\nexport TRACEWEAVE_SOURCE_GRAPH_RUNTIME_PLUSARGS_JSON='[\"+PROJECT+RUNTIME_MODE\"]'\n```\n\nThe value must be a JSON list of at most 256 exact, case-sensitive tokens.\nPrefix and wildcard matching are never used; unknown options remain\nfail-closed, and semantic `+define+`, `+incdir+`, and `+libext+` tokens cannot\nbe allowlisted. The private token text is not exposed in public receipts, but\nthe policy participates in cache identity. Restart or reconnect the MCP server\nafter changing it.\n\n`TRACEWEAVE_SOURCE_GRAPH_TIMEOUT` is a finite worker deadline in seconds\n(`0.001..86400`); the default remains 120. Every attempted preparation reports\nthe validated value as `source_graph.effective_timeout_sec`. Exact overlapping\nbuilds share one live worker even when the compile manifest is incomplete, but\nan incomplete artifact is still never inserted into the memory or disk cache.\nAfter a successful content-anchored incomplete build, the runtime may retain one\nbounded, one-shot session handoff for the next exact artifact request (including\nthe same effective timeout): at most one entry, 512 MiB, and 60 seconds. The\nconsumer removes it immediately; it is never searched by dominating scope and\nstill reports `cache_disposition=\"bypass_incomplete_key\"`, with\n`artifact_reuse=\"session_handoff\"` and `cache_tier=\"handoff\"`. Missing content\nidentity, incomplete snapshots, implicit scope, oversize artifacts, expiry, and\nfailed/timed-out/cancelled builds all rebuild normally. Cancelling one live\nwaiter leaves the worker alive for the others; cancelling all waiters terminates\nit.\n\nWhen a usable KDB is present but you specifically need to exercise Source Graph\nfor a driver, load, path, or X-trace test, select it explicitly:\n\n```bash\nexport TRACEWEAVE_CONNECTIVITY_ROUTE=source_graph\n```\n\nThis does not rename, move, or invalidate the KDB. It avoids constructing or\ncalling NPI for those four public connectivity tools and for the optional\n`build_tb_hierarchy` file/line overlay, then uses the normal Source\nGraph-to-Static fallback if Source Graph cannot answer safely. Hierarchy\ntopology still comes from the compile log; its `project` receipt reports\n`source_info_overlay=\"compile_log\"` and\n`source_info_overlay_reason=\"npi_skipped_by_policy\"`. The connectivity\nreceipt keeps `kdb_validation_status=\"usable\"`, reports\n`connectivity_route=\"source_graph\"`, and records the NPI attempt as\n`status=\"skipped\"` with `reason=\"npi_skipped_by_policy\"`. Unset the variable or\nset it to `auto` to restore the default trusted NPI -> Source Graph -> Legacy\nStatic route. Invalid values preserve `auto` and surface the fixed\n`connectivity_route_config_invalid` receipt instead of silently changing the\nroute.\n\nOn large parameterized SoCs, the bounded frontend tolerates compile-hierarchy\ncandidates removed by the selected generate specialization: it records an\ninconclusive `focused_instance_not_elaborated` coverage gap and continues with\nthe instances that really elaborated. Packed selects are checked against the\ndeclared range before expansion, so an unsigned parameter underflow in an\ninactive branch cannot materialize an enormous host-language range. During\nX-trace, an inconclusive parent-net query may request that parent's direct\nchildren as a bounded frontier; TraceWeave rebuilds the exact ancestor union\nand restarts at the original X-bearing signal. The expansion remains capped by\n`TRACEWEAVE_SOURCE_GRAPH_FRONTIER_MAX_INSTANCES`, and exceeding the cap falls\nback honestly rather than enumerating the design.\n\nDriver resolution is bit-mapping based, not an exact-whole-bus heuristic. For\nexample, a binding such as `.instr_rdata_i({8'h0, instr_rdata_core})` can report\nthe constant-driven upper byte and the 24-bit signal-driven lower segment\nseparately. Positive segments remain usable under partial coverage; only a\ncomplete artifact can prove an uncovered segment has no driver.\n\nSource Graph results expose this distinction explicitly in the additive\n`claim_semantics` receipt. The existing `confidence` field is unchanged and\nremains the conservative combination of positive evidence and global artifact\ncoverage. Consumers should interpret the new fields independently:\n\n- `positive_fact_confidence`: confidence in the returned positive source fact;\n- `target_bit_coverage`: whether the requested driver/load bits were all resolved;\n- `global_coverage_status`: coverage of the bounded artifact, including unrelated\n  unsupported constructs;\n- `exhaustive_search`: whether the operation searched its supported space\n  exhaustively (a positive path returns the first proved path and is not exhaustive);\n- `exclusive_driver_proved`: whether every requested driver bit has an exhaustive,\n  non-overlapping driver set;\n- `negative_claim_allowed`: whether “no driver/load/path exists” is a sound claim.\n\nFor example, a large SoC driver result may retain legacy `confidence=\"partial\"`\nand `coverage_status=\"inconclusive\"` while reporting\n`positive_fact_confidence=\"exact\"` and `target_bit_coverage=\"complete\"`. The\nreturned bit-mapped driver is then usable, but the caller must not call it the\nonly possible driver unless `exclusive_driver_proved=true`, and must not turn an\nempty result into a negative conclusion unless `negative_claim_allowed=true`.\n`trace_x_source` preserves the same receipt on each Source Graph chain node.\n\nWarm driver/load graph walks are independently resource-bounded, even after a\nlarge IR has been built. The fixed defaults admit 4,096 visited states, 16,384\ninspected IR edges, 256 unique matches, and 4,096 expansion frontiers. The\nwalk checks cooperative cancellation at state and edge boundaries and sorts\nits indexes before selecting a bounded result, so the same canonical IR yields\nthe same retained facts. Hitting any bound sets `query_truncated=true`, the\nspecific `*_truncated` flag and `query_*_limit` coverage gap, and forces\n`coverage_status=\"inconclusive\"`. Returned facts remain positively proved, but\n`exhaustive_search=false`, `exclusive_driver_proved=false` for drivers, and\n`negative_claim_allowed=false`; a high-fanout load list must therefore never be\ndescribed as complete. The public MCP inputs are unchanged in this slice.\n\nThe synthetic query benchmark runs each mode in a fresh process and reports\nquery/serialization time, result bytes, RSS, limits, and stable-result status:\n\n```bash\npython3.11 scripts/benchmark_source_graph_query.py --fanout 50000 --mode bounded\npython3.11 scripts/benchmark_source_graph_query.py --fanout 50000 --mode full\n```\n\nSignal-to-instance resolution is also indexed independently of design size:\nthe query engine probes dotted hierarchy prefixes from deepest to shallowest\nagainst the instance table instead of sorting and scanning every instance.\nWide-load matching constructs a requested-bit membership set once per match,\nwhile retaining the ordered bit tuples required for ascending ranges and concat\nmappings. These are internal changes; public paths, bit ordering, receipts, and\nschemas are unchanged. Reproduce the 30k-instance and 4,096-bit workloads with:\n\n```bash\npython3.11 scripts/benchmark_connectivity_query_indexes.py \\\n  --workload instance-resolution --size 30000 --repeats 100\npython3.11 scripts/benchmark_connectivity_query_indexes.py \\\n  --workload wide-load --size 4096 --repeats 100\npython3.11 scripts/benchmark_connectivity_query_indexes.py \\\n  --workload path-chain --size 4096 --repeats 10\npython3.11 scripts/benchmark_connectivity_query_indexes.py \\\n  --workload path-comb --size 4096 --repeats 10\n```\n\nThe IR still uses explicit ordered bit tuples. A wider interval/segment rewrite\nis deliberately deferred until a measured workload justifies its schema,\ncache-version, and correctness cost. The path workloads independently expose\ndeep-path CPU cost and queued shared-prefix memory, so path-search storage can\nbe optimized without conflating it with instance or packed-bit representation.\nOn Linux 4.18 with CPython 3.11.13 and an AMD Ryzen 7 5700G, three paired fresh-\nprocess runs at 4,096 edges reduced the process-median `path-chain` query from\n39.47 to 24.78 ms (1.59x) and `path-comb` from 77.12 to 20.87 ms (3.69x).\n`path-comb` median maximum RSS fell from 63,900 to 31,464 KiB; the single-chain\ncase instead increased from 32,456 to 33,584 KiB because it trades one growing\nprefix for the predecessor table. Result fingerprints, statuses, visited-state\ncounts, traversed-edge counts, and truncation receipts were identical. A real\nOpenTitan two-fact short path remained effectively unchanged at 0.452 versus\n0.438 ms. A 100,000-instance lookup was 0.0037 ms median, and even a synthetic\n65,536-bit load was 75.6 ms while serializing a 3.44 MB public result, so numeric\nstable IDs, a hierarchy trie, and interval-bit IR remain evidence-gated rather\nthan part of this change.\n\nAn optional exact, content-addressed disk cache can reuse a validated scoped IR\nafter an MCP restart. It remains disabled by default:\n\n```bash\nexport TRACEWEAVE_SOURCE_GRAPH_DISK_CACHE=1\nexport TRACEWEAVE_SOURCE_GRAPH_DISK_CACHE_MAX_ENTRIES=8\nexport TRACEWEAVE_SOURCE_GRAPH_DISK_CACHE_MAX_BYTES=536870912\n```\n\nIt uses the existing `TRACEWEAVE_CACHE_DIR` root and stores its private\nnamespace under `source_graph/disk-v1/`. The process-memory exact/dominating\ncache is always checked first and performs no disk I/O on a hit. A memory miss\ndoes one direct exact-artifact lookup; there is no startup scan or disk-level\ndominating-scope search. Every fresh process still hashes and validates all\nordered source/support inputs, options, tops, and compile/hierarchy snapshots\nbefore the disk lookup. A verified hit skips the frontend worker, constructs a\nnew query engine, and enters the memory cache. Unknown, truncated, corrupt, or\nversion-mismatched entries are fixed-reason misses followed by the normal cold\nbuild; they are never connectivity negatives or Static results.\n\nMemory-level dominating reuse can cross two different dependency closures, but\nonly through explicit fail-closed containment proofs: the full compile\nmanifest, options, tops, frontend/schema versions, and compile/hierarchy\nsnapshots must match exactly; the cached ordered input set must contain every\nrequested input; and its proved hierarchy scope plus objective exclusions must\ndominate the request.\nThe reverse subset direction, changed source/snapshot/version, duplicate-input\nmanifest, or non-dominating sibling remains a miss. The selected payload still\ncomes from one cached artifact. Every projected artifact is contractually marked\n`compile_projection_pruned_inputs`, so coverage stays inconclusive and only\nproved positive facts are reusable. Disk lookup remains exact-only. A\nreproducible two-scope orchestration benchmark is available as:\n\n```bash\npython3.11 scripts/benchmark_source_graph_scope_reuse.py \\\n  --delay-ms 50 --repeats 5\n```\n\nTo compare the historical reactive two-build sequence against the bounded\nfirst-artifact policy on the same eligible SoC target, run each strategy in a\nfresh process. The report includes plan sizes, preparation/build/load time,\nworker and parent peak RSS, cache bytes, and a hash of the final public query\nresult:\n\n```bash\npython3.11 scripts/benchmark_source_graph_initial_scope.py \\\n  --compile-log /path/to/build.log --simulator vcs \\\n  --signal tb.dut.path.to.signal --operation driver --max-depth 20 \\\n  --strategy reactive-sequence\npython3.11 scripts/benchmark_source_graph_initial_scope.py \\\n  --compile-log /path/to/build.log --simulator vcs \\\n  --signal tb.dut.path.to.signal --operation driver --max-depth 20 \\\n  --strategy bounded-adjacent\n```\n\nFor a reproducible cross-restart observation on any SoC layout, use\n`scripts/soak_source_graph_soc.py`. It takes an explicit verification root,\ncompile log, simulation log, waveform, top, and an external JSON list of public\ndriver/load/path queries; no DVSim, FuseSoC, or Bazel directory convention is\nembedded. Every sample is a fresh process, and the script refuses a non-empty\ncache root unless `--resume` is explicit. Raw cache/telemetry stays under that\nowner-private root; the optional `--output` file contains numeric and\nfixed-label aggregates only. Run the script with `--help` for the complete\ninvocation.\n\nThe persisted canonical ConnectivityIR can contain protected-IP-derived\nstructural information. TraceWeave creates its namespace and entries with\nowner-only directory/file permissions (`0700`/`0600`), rejects symlinks and\nnon-regular entry files, publishes atomically, and applies deterministic entry\nand byte limits only on local lookup/publish/maintenance paths. Choose a trusted\nlocal `TRACEWEAVE_CACHE_DIR`; do not place this opt-in cache on an untrusted or\nshared filesystem. Failed, timed-out, or cancelled builds are not published.\n\nRun `build_tb_hierarchy` first, as in the standard workflow, so the request has\nan exact compile/hierarchy handle. `backend_status` then reports\n`selected_backend`, `attempted_backend`, `actual_backend`, the ordered\n`attempted_backends` chain, and a Source Graph receipt containing fixed blocke",
  "bytes": 60000,
  "sha": "df7393da0ed3f5ad4f4897008e8ce1dcd9544269758407980469027085b18d86",
  "repo_slug": "gokeshenzhen/traceweave",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_gokeshenzhen_traceweave_cc2ae78f/readme"
}