Add full shell, replaceable Omics adapter and bilingual interaction

Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
This commit is contained in:
Codex
2026-09-13 14:26:39 +02:00
parent 2d1b714ebe
commit d8a29bfbdd
207 changed files with 8570 additions and 2164 deletions
@@ -64,6 +64,69 @@ def test_owner_can_read_own_snapshot_but_not_another_owners(database_url):
bob.get(session_id)
def test_legacy_interaction_language_is_atomic_idempotent_and_owner_scoped(database_url):
session_id = str(uuid.uuid4())
owner = _repository(database_url, "language-owner")
foreign = _repository(database_url, "language-foreign")
owner.create(_manifest(session_id))
owner.write_artifact(session_id, "sql_final", "SELECT 'paziente' AS nome")
with pytest.raises(SessionError, match="Sessione non trovata"):
foreign.ensure_interaction_language(session_id, "en")
barrier = Barrier(2)
def pin(language):
barrier.wait()
return owner.ensure_interaction_language(session_id, language).manifest.interaction_language
with ThreadPoolExecutor(max_workers=2) as pool:
results = list(pool.map(pin, ["it", "en"]))
assert results[0] == results[1]
saved = owner.get(session_id)
repeated = owner.ensure_interaction_language(session_id, "fr")
assert repeated == saved
assert saved.artifacts["sql_final"] == "SELECT 'paziente' AS nome"
def test_cli_creation_and_resume_use_postgres_language_authority(database_url, monkeypatch, tmp_path):
import json
from types import SimpleNamespace
from sqlalchemy.engine import make_url
from typer.testing import CliRunner
from tht.cli import session_cmd
from tht.config import DatabaseConfig
url = make_url(database_url)
connection = SimpleNamespace(user=url.username, password=url.password, host=url.host,
port=url.port, database=url.database, sslmode="disable",
sslrootcert=None)
cfg = SimpleNamespace(language="it", session_storage=SimpleNamespace(connection=connection),
database=DatabaseConfig(database="testdb", user="u", password="p",
schema="public"),
paths=SimpleNamespace(sessions=tmp_path / "unused"))
monkeypatch.setattr(session_cmd, "_load_config_or_exit", lambda _: cfg)
monkeypatch.setenv("THT_PRINCIPAL_ISSUER", "portal")
monkeypatch.setenv("THT_PRINCIPAL_SUBJECT", "cli-language")
def invoke(*args):
result = CliRunner().invoke(session_cmd.session_app, list(args))
assert result.exit_code == 0, result.output
return result.stdout
session_id = json.loads(invoke("new", "Pazienti", "--interaction-language", "en", "--json"))["id"]
invoke("reopen", session_id)
assert json.loads(invoke("show", session_id, "--json"))["interaction_language"] == "en"
legacy = _manifest(str(uuid.uuid4()))
_repository(database_url, "cli-language").create(legacy)
invoke("reopen", legacy.id)
cfg.language = "en"
invoke("reopen", legacy.id)
assert json.loads(invoke("show", legacy.id, "--json"))["interaction_language"] == "it"
assert not cfg.paths.sessions.exists()
def test_named_decision_is_stale_after_postgres_ledger_reopen(database_url):
repository = _repository(database_url, "phase-owner")
session_id = str(uuid.uuid4())