From 950f88f23edffba965464cbf981fa8cd84cf0ea4 Mon Sep 17 00:00:00 2001 From: mptyl Date: Sun, 12 Jul 2026 05:59:13 +0200 Subject: [PATCH] fix(evidence): distinguish implicit corpus ownership --- .superpowers/sdd/evidence-task-5c-report.md | 7 +++++++ harness/tht/corpus/pipeline.py | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.superpowers/sdd/evidence-task-5c-report.md b/.superpowers/sdd/evidence-task-5c-report.md index dc17bc57..83aeff09 100644 --- a/.superpowers/sdd/evidence-task-5c-report.md +++ b/.superpowers/sdd/evidence-task-5c-report.md @@ -135,3 +135,10 @@ run reached unrelated Task 6 immutable-file tamper tests; those files were delib manifest, and that mismatched job, GC, and search paths perform no vector/filesystem mutations. Focused workspace-binding, search-pack, preprocess JSON, and scoped Ruff/diff tests pass. + +Compatibility follow-up: direct/internal `CorpusPipeline` instances now distinguish an omitted +workspace identity from an explicit config/job identity. An unbound instance adopts the persisted +ACTIVE owner (or `default` only for a brand-new direct corpus), preserving safe resume/GC tests and +the real pgvector lifecycle. Explicit config/job identities still fail closed on any mismatch. The +two reported regressions, workspace mismatch guards, real Docker lifecycle, scoped Ruff/diff, and +the full harness suite all pass. diff --git a/harness/tht/corpus/pipeline.py b/harness/tht/corpus/pipeline.py index a51027d9..61c148fd 100644 --- a/harness/tht/corpus/pipeline.py +++ b/harness/tht/corpus/pipeline.py @@ -70,7 +70,7 @@ class CorpusPipeline: self, *, store: CorpusStore, sources: list[EvidenceSource], embedder, vector_store: VectorStore, embedding_model: str, embedding_dimensions: int, chunk_policy: ChunkPolicy, pipeline_version: str, retain_published_generations: int = 3, - workspace_id: str = "default", + workspace_id: str | None = None, ) -> None: self.store = store self.sources = sources @@ -88,8 +88,13 @@ class CorpusPipeline: def _assert_workspace_binding(self) -> None: manifest = self.store.active_manifest() if manifest is None: + if self.workspace_id is None: + self.workspace_id = "default" return persisted = manifest.metadata.get("workspace_id") + if self.workspace_id is None and isinstance(persisted, str): + self.workspace_id = persisted + return if persisted != self.workspace_id: raise PipelineError( "corpus belongs to a different workspace; use a new corpus root or explicit rebuild"