6.5 KiB
id, type, title, domain, status, owner, topic_slug, created, updated, state_hub_workstream_id
| id | type | title | domain | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|
| CUST-WP-0021 | workplan | State Hub — Multi-Host Repo Path Hardening | custodian | done | custodian | custodian | 2026-03-18 | 2026-03-18 | 516ca332-5eac-4d6e-8bf9-b2694ed34276 |
State Hub — Multi-Host Repo Path Hardening
Summary
When a kaizen-agentic worker on COULOMBCORE calls file-system-touching MCP tools (validate_repo_adr, check_repo_consistency, ingest_sbom), the MCP server runs those scripts on its own machine (bnt-lap001) against its own copy of the repo. Two problems emerge:
-
Wrong path:
validate_repo_adrandingest_sbom_tooltake raw filesystem paths as input. A remote agent passes their local path (e.g./home/tegwick/the-custodian) which does not exist on the server. -
Stale state: Even when path resolution works, the server runs against its own checkout. A remote agent ahead on a branch gets misleading results.
Design Boundary (documented, not fixed)
The MCP server is a subprocess on bnt-lap001. It can only read files from
bnt-lap001's filesystem. File-system tools will always operate against the
server's copy. The correct workflow for remote agents working on an ahead
branch is: push/sync first, or run consistency_check.py locally with
--api-base http://127.0.0.1:18000 rather than via the MCP tool.
This rule is documented in TOOLS.md.
Resolves
- validate_repo_adr raw-path input (broken for remote callers)
- ingest_sbom_tool raw lockfile path (same problem)
- host_paths empty for all repos except kaizen-agentic
- No error when server lacks the repo — silent wrong results
Tasks
T01 — Register COULOMBCORE host_paths for all repos it has
id: CUST-WP-0021-T01
status: done
priority: high
state_hub_task_id: "cf2c0449-9250-4425-925b-302482d75a11"
COULOMBCORE hostname: 254.130.205.92.host.secureserver.net
Repos present at /home/tegwick/<slug>:
| repo slug | COULOMBCORE path |
|---|---|
| the-custodian | /home/tegwick/the-custodian |
| kaizen-agentic | /home/tegwick/kaizen-agentic |
| ops-bridge | /home/tegwick/ops-bridge |
| marki-docx | /home/tegwick/marki-docx |
| railiance-cluster | /home/tegwick/railiance-cluster |
| railiance-infra | /home/tegwick/railiance-infra |
Also register bnt-lap001 paths for all repos currently using only local_path
(migrate them into host_paths so the map is the canonical source):
| repo slug | bnt-lap001 path |
|---|---|
| the-custodian | /home/worsch/the-custodian |
| kaizen-agentic | /home/worsch/kaizen-agentic |
| ops-bridge | /home/worsch/ops-bridge |
| activity-core | /home/worsch/activity-core |
| markitect-project | /home/worsch/markitect_project |
| railiance-apps | /home/worsch/railiance-apps |
| railiance-cluster | /home/worsch/railiance-cluster |
| railiance-enablement | /home/worsch/railiance-enablement |
| railiance-hosts | /home/worsch/railiance-infra |
| railiance-infra | /home/worsch/railiance-infra |
| railiance-platform | /home/worsch/railiance-platform |
| key-cape | /home/worsch/key-cape |
| net-kingdom | /home/worsch/net-kingdom |
Use POST /repos/{slug}/paths/ with {"host": "<hostname>", "path": "<path>"}.
T02 — Fix validate_repo_adr: accept repo_slug, resolve path from DB
id: CUST-WP-0021-T02
status: done
priority: high
state_hub_task_id: "52ed094a-4216-4cd1-a634-a29b82f26ec5"
Change validate_repo_adr(repo_path: str, ...) to
validate_repo_adr(repo_slug: str, ...) in mcp_server/server.py.
Resolution logic (same as _kaizen_agents_dir()):
- Fetch repo record via
_get(f"/repos/{repo_slug}") hostname = socket.gethostname()path = host_paths.get(hostname) or repo.get("local_path") or ""- If path is empty or not a directory: return a clear error message with instructions for remote agents to run the script locally.
- Pass the resolved path to the validate_repo_adr.py subprocess as before.
Update the tool docstring to document the new parameter and the design boundary (tool always runs against the server's copy).
T03 — Fix ingest_sbom_tool: resolve lockfile via repo_slug + relative path
id: CUST-WP-0021-T03
status: done
priority: medium
state_hub_task_id: "2a67d5e2-f581-490c-b42e-0f7d37979c0a"
Change ingest_sbom_tool(repo_slug, lockfile_path: str) so lockfile_path
becomes optional and is interpreted as relative to the repo root when
provided (not absolute). When omitted, the script auto-detects the lockfile
(existing behaviour with --repo-path).
Resolution logic:
- Fetch repo record, resolve path via
host_paths[hostname]/local_path - If path empty/missing: return clear error
- If
lockfile_pathprovided and is relative: join with resolved repo root - If
lockfile_pathis absolute: use as-is (backward compat), but emit a deprecation warning in the result string - Pass
--repo-path <resolved>and optionally--lockfile <lockfile>to script
T04 — Add host-path guard to check_repo_consistency
id: CUST-WP-0021-T04
status: done
priority: medium
state_hub_task_id: "3885497e-c491-4ddf-811f-0f0d19a0fc42"
check_repo_consistency already resolves paths correctly via the script.
But when host_paths is empty and local_path is absent the script silently
skips file checks. Add a pre-flight guard in the MCP tool:
- Fetch the repo record before spawning the subprocess
- Run
resolve_repo_pathlogic:host_paths[hostname]→local_path - If empty: return an early error message:
⚠ No path registered for this host (bnt-lap001). Register with: update_repo_path(repo_slug, "/path/to/repo") Remote agents: run consistency_check.py locally with --api-base http://127.0.0.1:18000 - If path is set but directory doesn't exist: same error (not just empty string)
T05 — Document design boundary in TOOLS.md
id: CUST-WP-0021-T05
status: done
priority: low
state_hub_task_id: "b4ba8cd0-1093-43ce-8a5d-03529e3c0588"
Add a section to state-hub/mcp_server/TOOLS.md under a new heading
"## Multi-Host & Remote Agent Usage" that explains:
- File-sys tools (validate_repo_adr, check_repo_consistency, ingest_sbom) always execute on the MCP server machine against its registered path
- Remote agents on a different branch/ahead-of-server should sync first
OR run the scripts locally with
--api-base http://127.0.0.1:18000 - How to register a new host's path:
update_repo_path(slug, path, host) - Pure-API tools (get_state_summary, create_task, etc.) work from any host