feat(z01): 낱값 마디 이름 넷 확정 · 값·설명 표시를 kind 낱말로

- 브레인 확정 이름 그대로 — `synthetic_tables["@values"]` 표 이름 「낱값」 · 설명 「표가 아닌 한 값들」 ·
  열 `@name` 「항목」 · `@value` 「값」 · `@path` 「원문 자리」(숨김)
- 값 묶음 표시를 참·거짓이 아니라 **낱말** `kind: "value" | "doc"` 로 둠 — 수식 같은 갈래가 늘면
  낱말만 더하면 되고 뜻이 안 뒤집힘 · 갈래(kinds) 말투와도 맞음
- 이름 갈이 — `role` → `kind` · `value_roles` → `value_kinds` · `counts.value_groups_by_kind` ·
  `policy.value_kind_rule`
- 셈은 그대로(값 49 · 설명 123) · 시험 26건(2건 늘, 낱값 마디 이름 넷과 낱말 여부를 잡음)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFCnEYNH4tsS2MbHvzBhZk
This commit is contained in:
2026-09-15 19:24:01 +09:00
co-authored by Claude Opus 5
parent 3a09a51a39
commit 8fb1952ba9
2 changed files with 229 additions and 188 deletions
File diff suppressed because it is too large Load Diff
+24 -10
View File
@@ -330,26 +330,40 @@ def test_줄_이름_열의_이름이_표마다_제_것이다(labels):
assert duplicated <= {"출처 키"}, f"줄 이름이 겹친다: {sorted(duplicated)}" assert duplicated <= {"출처 키"}, f"줄 이름이 겹친다: {sorted(duplicated)}"
def test_값_묶음마다_값이냐_설명이냐가_적혀_있다(labels): def test_값_묶음마다_kind_가_낱말로_적혀_있다(labels):
known = set(labels["value_roles"]) known = set(labels["value_kinds"])
bad = [] bad = []
for entry in labels["files"]: for entry in labels["files"]:
for group in entry["value_groups"]: for group in entry["value_groups"]:
if group.get("role") not in known: if group.get("kind") not in known:
bad.append(f"{entry['file_id']}::{group['key']}{group.get('role')!r}") bad.append(f"{entry['file_id']}::{group['key']}{group.get('role')!r}")
assert not bad, f"값·설명이 안 갈린 값 묶음: {bad}" assert not bad, f"값·설명이 안 갈린 값 묶음: {bad}"
def test_값_갈래_잣대가_이름표에_적혀_있다(labels): def test_값_갈래_잣대와_낱값_마디가_적혀_있다(labels):
rule = labels["policy"]["value_role_rule"] rule = labels["policy"]["value_kind_rule"]
assert "금액이 움직이나" in rule assert "금액이 움직이나" in rule
assert labels["policy"]["row_key_column"] assert labels["policy"]["row_key_column"]
node = labels["synthetic_tables"]["@values"]
assert node["name_ko"] == "낱값"
assert node["summary"] == "표가 아닌 한 값들"
assert [c["key"] for c in node["columns"]] == ["@name", "@value", "@path"]
assert [c["name_ko"] for c in node["columns"]] == ["항목", "", "원문 자리"]
assert node["columns"][2]["visible"] is False
def test_값_갈래는_참거짓이_아니라_낱말이다(labels):
"""수식 같은 갈래가 늘면 낱말만 더하면 된다 — 참·거짓이면 그때 뜻이 뒤집힌다."""
for entry in labels["files"]:
for group in entry["value_groups"]:
assert isinstance(group["kind"], str), f"{entry['file_id']}::{group['key']}"
assert set(labels["value_kinds"]) == {"value", "doc"}
def test_한_값짜리_요율은_값으로_선다(labels): def test_한_값짜리_요율은_값으로_선다(labels):
"""산재 3.56 % 처럼 원가에 그대로 드는 요율이 설명으로 숨으면 트리에서 사라진다.""" """산재 3.56 % 처럼 원가에 그대로 드는 요율이 설명으로 숨으면 트리에서 사라진다."""
rates = next(f for f in labels["files"] if f["file_id"] == "rates") rates = next(f for f in labels["files"] if f["file_id"] == "rates")
by_key = {g["key"]: g["role"] for g in rates["value_groups"]} by_key = {g["key"]: g["kind"] for g in rates["value_groups"]}
for key in ( for key in (
"variables/rate_sanjae", "variables/rate_sanjae",
"variables/rate_health", "variables/rate_health",
@@ -360,12 +374,12 @@ def test_한_값짜리_요율은_값으로_선다(labels):
"variables/rate_asbestos_contribution", "variables/rate_asbestos_contribution",
): ):
assert by_key.get(key) == "value", f"{key} 가 값으로 안 섰다" assert by_key.get(key) == "value", f"{key} 가 값으로 안 섰다"
assert by_key.get("processing_rules") == "note" assert by_key.get("processing_rules") == "doc"
def test_세어_둔_갈래_수가_실제와_같다(labels): def test_세어_둔_값_갈래_수가_실제와_같다(labels):
counted: dict[str, int] = {} counted: dict[str, int] = {}
for entry in labels["files"]: for entry in labels["files"]:
for group in entry["value_groups"]: for group in entry["value_groups"]:
counted[group["role"]] = counted.get(group["role"], 0) + 1 counted[group["kind"]] = counted.get(group["kind"], 0) + 1
assert counted == labels["counts"]["value_groups_by_role"] assert counted == labels["counts"]["value_groups_by_kind"]