fix(mcp): stage ingest uploads outside vault

Move remote MCP ingest uploads from the vault inbox to the MCP runtime staging area so uploaded files are not accepted into the vault before wiki-ingest processes them.

Reject ingest runtime roots that resolve inside the vault, and update the generated OpenCode prompt plus docs to describe uploads as temporary staging inputs.

Validation: python3 -m unittest discover -v; python3 -m py_compile obsidian_wiki/mcp_ingest.py tests/test_mcp_ingest.py; git diff --check
This commit is contained in:
Codex
2026-07-05 15:04:16 +00:00
parent 691e5aa8ea
commit e7adfbe9a6
5 changed files with 36 additions and 4 deletions
+16
View File
@@ -43,6 +43,21 @@ class McpIngestTests(unittest.TestCase):
self.assertFalse(parse_bool("0"))
self.assertFalse(parse_bool("false"))
def test_uploads_are_staged_in_runtime_not_vault(self):
upload = self.manager.create_upload(file_name="drawing.pdf", size_bytes=0, sha256=self._sha256(b""))
upload_path = Path(upload["path"]).resolve()
self.assertTrue(upload_path.is_relative_to((self.runtime / "uploads").resolve()))
self.assertFalse(upload_path.is_relative_to(self.vault.resolve()))
def test_runtime_root_must_not_be_inside_vault(self):
with self.assertRaises(IngestError):
IngestManager(
vault_path=self.vault,
project_root=self.project,
runtime_root=self.vault / ".runtime" / "mcp-ingest",
)
def test_upload_chunk_lifecycle_verifies_offset_size_and_sha(self):
payload = b"hello ingest"
upload = self.manager.create_upload(
@@ -111,6 +126,7 @@ class McpIngestTests(unittest.TestCase):
prompt = args[-1]
self.assertIn("/wiki-ingest", prompt)
self.assertIn(str(Path(upload["path"])), prompt)
self.assertIn("temporary runtime staging files", prompt)
self.assertIn("Do not ingest any file outside this list.", prompt)
self.assertIn("obsidian-wiki file-index rebuild", prompt)
self.assertNotIn("../secret", prompt)