fix(register): require explicit topic when ambiguous
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06d83-1cbc-71f2-b0dc-e0f48cedae43
This commit is contained in:
parent
803bb95e1d
commit
e663f209f7
4 changed files with 209 additions and 4 deletions
|
|
@ -16,6 +16,7 @@ from statehub_register import (
|
|||
project_registration_plan,
|
||||
refuse_project_flavor_scaffold,
|
||||
run_register,
|
||||
_find_or_create_topic,
|
||||
_invoke_llm,
|
||||
_normalise_inference,
|
||||
_parse_json_object,
|
||||
|
|
@ -265,6 +266,7 @@ def _register_args(path: Path, **overrides):
|
|||
"repo_slug": None,
|
||||
"wp_prefix": None,
|
||||
"domain": "infotech",
|
||||
"topic": None,
|
||||
"description": "Test project.",
|
||||
"intent": None,
|
||||
"api_base": "http://unused",
|
||||
|
|
@ -333,6 +335,120 @@ def test_run_register_existing_project_skips_scaffold_and_templating(
|
|||
assert not (repo / "INTENT.md").exists()
|
||||
|
||||
|
||||
def test_run_register_honors_explicit_topic_slug(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
):
|
||||
repo = tmp_path / "demo-service"
|
||||
repo.mkdir()
|
||||
written, registered = _stub_register_io(monkeypatch)
|
||||
monkeypatch.setattr(
|
||||
"statehub_register._api_get",
|
||||
lambda path, *_a, **_k: (
|
||||
[{"slug": "infotech", "id": "dom-1"}]
|
||||
if str(path).startswith("/domains")
|
||||
else [
|
||||
{"id": "topic-1", "slug": "custodian", "domain_slug": "infotech"},
|
||||
{"id": "topic-2", "slug": "activity-core", "domain_slug": "infotech"},
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
run_register(
|
||||
_register_args(
|
||||
repo,
|
||||
topic="activity-core",
|
||||
intent="Register the demo service with the requested topic.",
|
||||
)
|
||||
)
|
||||
|
||||
assert written[0]["topic_id"] == "topic-2"
|
||||
repo_registration = next(item for kind, item in registered if kind == "repo")
|
||||
assert repo_registration["topic_id"] == "topic-2"
|
||||
|
||||
|
||||
def test_topic_selection_refuses_ambiguous_domain(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
monkeypatch.setattr(
|
||||
"statehub_register._api_get",
|
||||
lambda *_a, **_k: [
|
||||
{"id": "topic-1", "slug": "custodian", "domain_slug": "infotech"},
|
||||
{"id": "topic-2", "slug": "activity-core", "domain_slug": "infotech"},
|
||||
],
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit, match=r"Pass --topic <slug>"):
|
||||
_find_or_create_topic(
|
||||
"infotech",
|
||||
"demo",
|
||||
"demo",
|
||||
RegisterInference(),
|
||||
"http://unused",
|
||||
)
|
||||
|
||||
|
||||
def test_topic_selection_uses_exact_inferred_topic(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
topics = [
|
||||
{"id": "topic-1", "slug": "custodian", "domain_slug": "infotech"},
|
||||
{"id": "topic-2", "slug": "activity-core", "domain_slug": "infotech"},
|
||||
]
|
||||
monkeypatch.setattr("statehub_register._api_get", lambda *_a, **_k: topics)
|
||||
|
||||
selected = _find_or_create_topic(
|
||||
"infotech",
|
||||
"activity-core",
|
||||
"activity-core",
|
||||
RegisterInference(topic_slug="activity-core"),
|
||||
"http://unused",
|
||||
)
|
||||
|
||||
assert selected == topics[1]
|
||||
|
||||
|
||||
def test_topic_selection_refuses_cross_domain_topic(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
monkeypatch.setattr(
|
||||
"statehub_register._api_get",
|
||||
lambda *_a, **_k: [
|
||||
{"id": "topic-1", "slug": "activity-core", "domain_slug": "agents"},
|
||||
],
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit, match=r"belongs to domain\(s\) agents"):
|
||||
_find_or_create_topic(
|
||||
"infotech",
|
||||
"demo",
|
||||
"demo",
|
||||
RegisterInference(),
|
||||
"http://unused",
|
||||
requested_topic_slug="activity-core",
|
||||
)
|
||||
|
||||
|
||||
def test_topic_selection_refuses_missing_explicit_topic(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
monkeypatch.setattr(
|
||||
"statehub_register._api_get",
|
||||
lambda *_a, **_k: [
|
||||
{"id": "topic-1", "slug": "custodian", "domain_slug": "infotech"},
|
||||
],
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit, match=r"Available: custodian"):
|
||||
_find_or_create_topic(
|
||||
"infotech",
|
||||
"demo",
|
||||
"demo",
|
||||
RegisterInference(),
|
||||
"http://unused",
|
||||
requested_topic_slug="activity-core",
|
||||
)
|
||||
|
||||
|
||||
def test_write_registration_files_is_idempotent_without_force(tmp_path: Path):
|
||||
inference = RegisterInference()
|
||||
kwargs = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue