fix: render registry workspaces for harness

This commit is contained in:
2026-08-05 16:03:45 +02:00
parent ece9cfda50
commit bd798b1c96
21 changed files with 659 additions and 69 deletions
+60
View File
@@ -6,6 +6,7 @@ from tht.config import (
PostgresDwhConfig,
ThothRestDwhConfig,
ThothVectorHttpConfig,
workspace_id_for_config,
load_config,
)
from tht.adapters.evidence import FilesystemEvidenceSource, HttpManifestEvidenceSource
@@ -86,6 +87,65 @@ roots:
assert cfg.roots.sessions.as_posix() == "build/sessions"
def test_runtime_handoff_preserves_canonical_identity_and_durable_roots(monkeypatch, tmp_path):
data_root = tmp_path / "data"
runtime_root = data_root / "sessions" / "psd-clinical"
workspace = tmp_path / "runtime-random-uuid.yaml"
workspace.write_text(f"""
runtime_identity:
workspace_id: psd-clinical
workspace_revision: {'a' * 40}
dwh:
type: postgres_direct
connection: {{database: analytics, schema: mart, user: reader, password: secret}}
vectors:
type: pgvector_direct
connection: {{database: analytics, schema: vectors, user: vector, password: secret}}
roots:
sessions: {runtime_root / 'sessions'}
artifacts: {runtime_root / 'artifacts'}
indexes: {runtime_root / 'indexes'}
embeddings: {{base_url: http://embedding.invalid, model: embed, dim: 768}}
""")
monkeypatch.setenv("THT_DATA_ROOT", str(data_root))
cfg = load_config(workspace)
assert cfg._workspace_id == "psd-clinical"
assert cfg._workspace_revision == "a" * 40
assert cfg.paths.sessions == runtime_root / "sessions"
assert cfg.paths.artifacts == runtime_root / "artifacts"
assert cfg.paths.indexes == runtime_root / "indexes"
def test_runtime_identity_is_authoritative_over_runtime_filename(tmp_path):
workspace = tmp_path / "runtime-random-uuid.yaml"
workspace.write_text(f"""
runtime_identity:
workspace_id: psd-clinical
workspace_revision: {'a' * 40}
dwh:
type: postgres_direct
connection: {{database: analytics, schema: mart, user: reader, password: secret}}
roots: {{sessions: sessions, artifacts: artifacts, indexes: indexes}}
""")
cfg = load_config(workspace)
assert workspace_id_for_config(cfg, workspace) == "psd-clinical"
def test_load_config_rejects_executable_yaml_tags_without_running_them(tmp_path):
marker = tmp_path / "must-not-exist"
workspace = tmp_path / "workspace.yaml"
workspace.write_text(f"dwh: !command touch {marker}\n")
with pytest.raises(ConfigError, match="YAML|configurazione"):
load_config(workspace)
assert not marker.exists()
def test_loads_direct_discriminated_resources(tmp_path):
workspace = tmp_path / "workspace.yaml"
workspace.write_text(
+3 -3
View File
@@ -5,7 +5,7 @@ import typer
from tht.cli.config_cmd import CONFIG_OPT
from tht.cli.schema_cmd import _load_config_or_exit
from tht.config import workspace_id_from_path
from tht.config import workspace_id_for_config
KIND_MAP = {
"evidence": ["evidence"],
@@ -60,7 +60,7 @@ def search_cmd(
cfg = _load_config_or_exit(config)
from tht.search.evidence import validate_corpus_workspace
workspace_id = workspace_id_from_path(config)
workspace_id = workspace_id_for_config(cfg, config)
validate_corpus_workspace(cfg, workspace_id)
dwh_snapshot = _leased_dwh_snapshot(cfg, ctx)
require_vector_cfg(cfg)
@@ -264,7 +264,7 @@ def pack_cmd(
cfg = _load_config_or_exit(config)
from tht.search.evidence import validate_corpus_workspace
workspace_id = workspace_id_from_path(config)
workspace_id = workspace_id_for_config(cfg, config)
validate_corpus_workspace(cfg, workspace_id)
dwh_snapshot = _leased_dwh_snapshot(cfg, ctx)
require_vector_cfg(cfg)
+24 -2
View File
@@ -162,6 +162,11 @@ class PathsConfig(BaseModel):
sessions: Path = Path("sessions")
class RuntimeIdentityConfig(BaseModel):
workspace_id: str = Field(pattern=r"^[a-z][a-z0-9-]{2,62}$")
workspace_revision: str = Field(pattern=r"^[0-9a-f]{40}$")
class WorkspaceRoots(PathsConfig):
pass
@@ -305,7 +310,9 @@ class ExecutionConfig(BaseModel):
class Config(BaseModel):
_workspace_id: str = PrivateAttr(default="default")
_workspace_revision: str | None = PrivateAttr(default=None)
_config_source: str = PrivateAttr(default="direct")
runtime_identity: RuntimeIdentityConfig | None = None
dwh: DwhResourceConfig
vectors: VectorResourceConfig | None = None
session_storage: SessionStorageConfig | None = None
@@ -354,10 +361,20 @@ def workspace_id_from_path(path: Path) -> str:
return path.resolve().stem.lower().replace(".", "-").replace("_", "-")
def workspace_id_for_config(config: Config, path: Path) -> str:
"""Return the canonical runtime identity, falling back for legacy configs."""
if config.runtime_identity is not None:
return config.runtime_identity.workspace_id
return workspace_id_from_path(path)
def load_config(path: Path) -> Config:
if not path.exists():
raise ConfigError(f"File di configurazione non trovato: {path}")
raw = yaml.safe_load(path.read_text())
try:
raw = yaml.safe_load(path.read_text())
except yaml.YAMLError as exc:
raise ConfigError(f"Configurazione YAML non valida: {path}") from exc
if not isinstance(raw, dict):
raise ConfigError(f"Configurazione non valida (atteso un mapping YAML): {path}")
expanded = _resolve_secret_files(_expand_env(raw))
@@ -407,7 +424,12 @@ def load_config(path: Path) -> Config:
FutureWarning,
stacklevel=2,
)
cfg._workspace_id = workspace_id_from_path(path)
cfg._workspace_id = workspace_id_for_config(cfg, path)
cfg._workspace_revision = (
cfg.runtime_identity.workspace_revision
if cfg.runtime_identity is not None
else None
)
cfg._config_source = path.resolve().as_posix()
return cfg