Files
kunail0804-ComfyUI-Scene-Co…/compiler/common/message_codes.py
T
50e7b0a8a4 feat(kb): automatic KB builder, ingestion & validation tooling (#35) (#139)
* feat(kb): automatic KB builder, ingestion & validation tooling (#35)

Closes #118, #119, #120, #121, #122.

- Ingest committed Danbooru alias/implication snapshots during generation:
  synonyms reach canonicals (long black stockings -> thighhighs), implications
  become expand relations. Curated-wins preserved.
- Automatic candidate validator (structural rules reused from kb_validation +
  confidence heuristic, no approval gate; SC0022).
- Duplicate/conflict detection tool (scripts/detect_kb_conflicts.py) + reusable
  detect_conflicts; clean reference KB reports zero.
- KB coverage benchmark harness (scripts/coverage_benchmark.py) + JSON summary.
- Single fully-automated, CI-runnable build pipeline (scripts/build_knowledge_base.py)
  that fails fast on rejections/conflicts and never prompts. Docs added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(kb): use pytest.approx for confidence float assertions (SonarCloud reliability)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: kunail0804 <kunail0804@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 18:10:17 +02:00

77 lines
2.8 KiB
Python

"""Central registry of compiler message codes (MASTER_SPEC §21.2, Appendix B).
Every diagnostic :class:`Message` uses a stable code from here, giving one source
of truth for a code's canonical severity and title. Codes SC0001-SC0014 come from
Appendix B; SC0015+ are extensions added as the compiler is implemented and are
intended to be folded back into Appendix B and the wiki.
Use :func:`message` to build a message so the severity and title always match the
code.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from compiler.common.result import Message, Severity
@dataclass(frozen=True)
class CodeSpec:
"""The canonical severity and title for a message code."""
severity: Severity
title: str
# Appendix B (SC0001-SC0014).
_APPENDIX_B: dict[str, CodeSpec] = {
"SC0001": CodeSpec(Severity.WARNING, "Unknown Concept"),
"SC0002": CodeSpec(Severity.ERROR, "Invalid Scene JSON"),
"SC0003": CodeSpec(Severity.ERROR, "Circular Expansion"),
"SC0004": CodeSpec(Severity.FATAL, "Knowledge Base Load Failure"),
"SC0005": CodeSpec(Severity.ERROR, "Duplicate Canonical ID"),
"SC0006": CodeSpec(Severity.WARNING, "Deprecated Concept"),
"SC0007": CodeSpec(Severity.WARNING, "Duplicate Tag Removed"),
"SC0008": CodeSpec(Severity.ERROR, "Invalid Category"),
"SC0009": CodeSpec(Severity.ERROR, "Missing Required Field"),
"SC0010": CodeSpec(Severity.ERROR, "Schema Version Mismatch"),
"SC0011": CodeSpec(Severity.ERROR, "Analyzer Schema Validation Failure"),
"SC0012": CodeSpec(Severity.FATAL, "Analyzer Unavailable"),
"SC0013": CodeSpec(Severity.ERROR, "Analyzer Timeout"),
"SC0014": CodeSpec(Severity.FATAL, "Invalid Configuration"),
}
# Extensions beyond Appendix B (to be documented in the spec/wiki).
_EXTENSIONS: dict[str, CodeSpec] = {
"SC0015": CodeSpec(Severity.WARNING, "Unexpected Field Removed"),
"SC0016": CodeSpec(Severity.WARNING, "Empty Concept Removed"),
"SC0017": CodeSpec(Severity.WARNING, "Interaction Dropped"),
"SC0018": CodeSpec(Severity.ERROR, "Analyzer Unexpected Response"),
"SC0019": CodeSpec(Severity.WARNING, "Concept Reduced"),
"SC0021": CodeSpec(Severity.WARNING, "List Under-Transcription"),
"SC0022": CodeSpec(Severity.WARNING, "Candidate Rejected"),
}
CODES: dict[str, CodeSpec] = {**_APPENDIX_B, **_EXTENSIONS}
def message(code: str, description: str, **context: Any) -> Message:
"""Build a :class:`Message` for a registered code.
The severity and title are taken from the registry so they always match the
code; only the description and optional context vary per call.
Raises:
KeyError: If ``code`` is not registered.
"""
spec = CODES[code]
return Message(
code=code,
severity=spec.severity,
title=spec.title,
description=description,
context=context,
)