(work: Path)
| 138 | |
| 139 | |
| 140 | def run_checks(work: Path): |
| 141 | if len(sys.argv) > 1: |
| 142 | plugin_dir = Path(sys.argv[1]).resolve() |
| 143 | else: |
| 144 | plugin_dir = generate_plugin(work) |
| 145 | ok("generated plugin present", str(plugin_dir)) |
| 146 | |
| 147 | hermes_home = plugin_dir.parent.parent |
| 148 | os.environ["HERMES_HOME"] = str(hermes_home) |
| 149 | sys.path.insert(0, str(plugin_dir.parent)) |
| 150 | plugin = __import__("tracedecay") |
| 151 | assert Path(plugin.__file__).resolve() == (plugin_dir / "__init__.py").resolve() |
| 152 | ok("plugin package imports standalone (no hermes on sys.path)") |
| 153 | |
| 154 | header = (plugin_dir / "__init__.py").read_text(encoding="utf-8").splitlines()[0] |
| 155 | assert header.startswith("# Generated by tracedecay ") and "commit " in header, header |
| 156 | manifest = (plugin_dir / "plugin.yaml").read_text(encoding="utf-8") |
| 157 | assert "generator_commit: " in manifest, manifest.splitlines()[:5] |
| 158 | assert (plugin_dir / "cli.py").is_file() |
| 159 | ok("provenance stamp + cli passthrough generated") |
| 160 | |
| 161 | # ── 3. Registration split + provider dedup ────────────────────────── |
| 162 | # The installer wrote memory.provider: tracedecay into the temp profile |
| 163 | # config, so the provider-owned fact trio must NOT register as direct |
| 164 | # duplicates; transcript search has no provider twin and stays. |
| 165 | ctx = StubCtx() |
| 166 | plugin.register(ctx) |
| 167 | assert "tracedecay_search" in ctx.tools, sorted(ctx.tools) |
| 168 | assert "tracedecay_context" in ctx.tools, sorted(ctx.tools) |
| 169 | assert "tracedecay_message_search" in ctx.tools, sorted(ctx.tools) |
| 170 | assert "tracedecay_fact_store" not in ctx.tools, sorted(ctx.tools) |
| 171 | assert "tracedecay_fact_feedback" not in ctx.tools, sorted(ctx.tools) |
| 172 | assert "tracedecay_memory_status" not in ctx.tools, sorted(ctx.tools) |
| 173 | assert "tracedecay_lcm_compress" not in ctx.tools, sorted(ctx.tools) |
| 174 | assert "tracedecay_lcm_preflight" not in ctx.tools, sorted(ctx.tools) |
| 175 | # Context-engine native mirrors stay gated without the capability flag. |
| 176 | assert "lcm_grep" not in ctx.tools, sorted(ctx.tools) |
| 177 | ok("code-graph tools register; provider-owned fact tools dedup", f"{len(ctx.tools)} tools") |
| 178 | |
| 179 | class OtherProviderCtx(StubCtx): |
| 180 | def __init__(self): |
| 181 | super().__init__() |
| 182 | self.config = {"memory": {"provider": "honcho"}} |
| 183 | |
| 184 | other = OtherProviderCtx() |
| 185 | plugin.register(other) |
| 186 | assert "tracedecay_fact_store" in other.tools, sorted(other.tools) |
| 187 | ok("fact tools register when another memory provider is active") |
| 188 | |
| 189 | class ForwardingCtx(StubCtx): |
| 190 | context_engine_tool_handlers_receive_messages = True |
| 191 | |
| 192 | fwd = ForwardingCtx() |
| 193 | plugin.register(fwd) |
| 194 | assert "tracedecay_lcm_compress" in fwd.tools, sorted(fwd.tools) |
| 195 | assert "lcm_grep" in fwd.tools, sorted(fwd.tools) |
| 196 | ok("LCM live-ingest verbs register when the host forwards messages") |
| 197 |
no test coverage detected