fix(z01): 자재 할증 두 벌 관계 명기 · coef 암괴 중복 한 줄로 · 참고 사례 갈래 둘

- **이원화가 아님을 두 자리에 못박음** — `material_surcharge.original_tables`
  「원문 표는 coef/surcharge_mat」 · `coef.variables.surcharge_mat.used_value_at`
  「읽어 쓰는 값은 material_surcharge/rates_pct」. 저쪽은 원문 보관이라 읽는 코드가 0
- **암괴 중복 두 줄** — L·C 둘 다 첫 줄에 `duplicate_same_value`, 둘째 줄에 `hidden_duplicate` +
  사유 「원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠」.
  ⚠ 원본 줄은 안 지움 · `selection: pending` 과 「원문 오기 가능성」 주석 그대로 살림
  ⚠ 「역이 섞인 점질토」는 값이 달라 안 접음(L 1.35~1.4 ↔ 1.3~1.4)
- **참고 사례 갈래(`reference`) 새로 둠** — `structure_unit_observed`(울진소광 한 현장 관찰값) ·
  `revetment_sabang`(교본값에 설명 글 섞임). 트리엔 남되 기초데이터가 아님(사용자 판정).
  갈래 셈 로직 17 → 15 · 참고 사례 2
- 마스터 둘이 바뀌어 폴더 지문(`_manifest`) 둘 갱신 · 새 열 넷·값 묶음 둘 이름표 추가
- ⚠ `test_z01_master_data.py`(랩탑 메인)가 갈래 수를 박아 두어 함께 고침 — 데이터가 바뀌면
  따라가야 하는 상수임

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-16 13:08:52 +09:00
co-authored by Claude Opus 5
parent c58c38142c
commit 75ae9375d9
7 changed files with 114 additions and 17 deletions
@@ -13,8 +13,8 @@
"file": "coef_2026.json",
"dataset_id": "coef",
"effective_date": "2026-01-01",
"sha256": "0bc3fe981165e8d320b7c20f4535c545f2f54415427ac60205dac4a72dbb4f19",
"size_bytes": 29413
"sha256": "daba170cd806374c92e086dec69f9559271c0317a7426e66e9dc841c2ca264bd",
"size_bytes": 31715
},
{
"file": "fx_2026-08-14.json",
@@ -787,6 +787,7 @@
]
},
"surcharge_mat": {
"used_value_at": "resources/data_material_surcharge/material_surcharge_2026-01-01.json → rates_pct — ⚠ 코드가 읽어 쓰는 값은 저기다. 이 표는 원문 보관용이라 읽는 코드가 없다(두 벌이 아니다).",
"unit": "percent",
"representation": "full_source_tables",
"duplicate_application_prohibited": true,
@@ -1108,6 +1109,8 @@
"max": 1.45,
"duplicate_group": "암괴나 호박돌이 섞인 점토",
"duplicate_index": 1,
"duplicate_same_value": true,
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
"selection": "pending"
},
{
@@ -1129,6 +1132,9 @@
"max": 1.45,
"duplicate_group": "암괴나 호박돌이 섞인 점토",
"duplicate_index": 2,
"duplicate_same_value": true,
"hidden_duplicate": true,
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
"selection": "pending"
}
]
@@ -1210,6 +1216,8 @@
"max": 0.95,
"duplicate_group": "암괴나 호박돌이 섞인 점토",
"duplicate_index": 1,
"duplicate_same_value": true,
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
"selection": "pending"
},
{
@@ -1231,6 +1239,9 @@
"max": 0.95,
"duplicate_group": "암괴나 호박돌이 섞인 점토",
"duplicate_index": 2,
"duplicate_same_value": true,
"hidden_duplicate": true,
"duplicate_reason": "원문 두 줄 · 값 같음 — 화면에는 한 줄로 보임. 원문은 그대로 둠(임의 보정 없음).",
"selection": "pending"
}
]
@@ -2,14 +2,14 @@
"schema_version": "1.0",
"dataset_id": "data_master_labels",
"effective_date": "2026-01-01",
"generated_at": "2026-09-16T11:39:55+09:00",
"generated_at": "2026-09-16T13:00:09+09:00",
"note": "마스터 자료의 **사람이 읽을 이름표**. 값이 아니라 이름만 담는다 — 여기를 고쳐도 계산은 안 바뀐다. Z01 마스터 관리 화면이 표·열 이름을 여기서 읽는다.",
"policy": {
"labels_only": "값·수식·단가를 담지 않는다. 마스터 파일은 손대지 않는다.",
"no_invented_meaning": "뜻을 모르는 열은 name_ko 를 비우고 unknown 에 사유를 적는다. 지어내지 않는다.",
"unit_is_label_only": "unit 은 이름표에서만 정한다. 자료에 없는 단위를 만들어 붙이지 않는다.",
"counting_rule": "표 = 화면이 표로 그릴 마디(줄이 여럿인 마디). 값 묶음 = 표가 아닌 마디(설명·방침·한 값짜리 요율 따위).",
"brain_kind_table": "갈래는 2026-09-15 브레인 갈래 나눔표를 그대로 따른다(로직 17 · 기초값 9 · 부산물 4 · 씨앗 1).",
"brain_kind_table": "갈래는 2026-09-15 브레인 갈래 나눔표에서 출발한다(로직 17 · 기초값 9 · 부산물 4 · 씨앗 1). 2026-09-16 사용자 판정으로 `structure_unit_observed`·`revetment_sabang` 둘을 **참고 사례**로 옮겼다 — 한 현장 관찰값·교본 설명 섞임이라 기초데이터가 아니다(로직 15 · 참고 사례 2).",
"out_of_31": "폴더 지문(_manifest.json) 셋은 브레인 31 밖이다. 부산물이 아니라 **지문** 갈래로 둔다 — 계산이 남긴 기록이 아니라 어느 판으로 셈했는지 못박는 표라 「정본 아님」 딱지가 안 맞는다(2026-09-15 브레인 ②).",
"excluded": "강우 IDF 캐시(resources/data_rainfall_idf_cache, 96 파일)는 배수용이라 뺀다.",
"merged_tables_rule": "`merged_tables` 는 **기초단가 다섯**(노임·자재·유가·제비율·기계)을 화면이 한 표씩으로 보이려고 여러 원본 표를 모은 자리다. ⚠ **값을 옮기지 않는다** — 열 이름·단위·숨김과 `editable`(고칠 수 있나)만 담는다. `editable: false` 는 다른 값에서 나온 계산값이라 사람이 못 고친다. 기계는 한 표로 안 모이므로 `machine_cost_chain` 이 사슬을 적는다 (2026-09-15 사용자 지시 · 브레인).",
@@ -45,6 +45,10 @@
"name_ko": "지문",
"summary": "어느 판으로 셈했는지 못박는 자리. 값도 규칙도 아니고 **판을 가리키는 표**다 — 고치지 않는다."
},
"reference": {
"name_ko": "참고 사례",
"summary": "한 현장·한 교본에서 본 값. ⚠ 표준이 아니다 — 근거로 보되 기초데이터처럼 갈아 끼우지 않는다."
},
"seed": {
"name_ko": "씨앗",
"summary": "앞으로 늘려 갈 첫 벌. 모양을 잡아 두려고 먼저 놓은 것이다."
@@ -1090,11 +1094,11 @@
"merged_columns": 89,
"files": 34,
"tables": 91,
"columns": 456,
"value_groups": 173,
"columns": 462,
"value_groups": 175,
"unknown": 0,
"value_groups_by_kind": {
"doc": 107,
"doc": 109,
"value": 66
}
},
@@ -1484,6 +1488,24 @@
"name_ko": "채택 여부",
"unit": "",
"visible": true
},
{
"key": "duplicate_same_value",
"name_ko": "값 같은 중복",
"unit": "",
"visible": true
},
{
"key": "duplicate_reason",
"name_ko": "중복 사유",
"unit": "",
"visible": true
},
{
"key": "hidden_duplicate",
"name_ko": "접힌 줄",
"unit": "",
"visible": false
}
]
},
@@ -1529,6 +1551,24 @@
"name_ko": "채택 여부",
"unit": "",
"visible": true
},
{
"key": "duplicate_same_value",
"name_ko": "값 같은 중복",
"unit": "",
"visible": true
},
{
"key": "duplicate_reason",
"name_ko": "중복 사유",
"unit": "",
"visible": true
},
{
"key": "hidden_duplicate",
"name_ko": "접힌 줄",
"unit": "",
"visible": false
}
]
},
@@ -1665,6 +1705,12 @@
"name_ko": "값 단위",
"summary": "할증은 %다.",
"kind": "value"
},
{
"key": "variables/surcharge_mat/used_value_at",
"name_ko": "쓰는 값이 있는 자리",
"summary": "이 표는 원문 보관용이라 읽는 코드가 없다. 값은 `material_surcharge` 의 `rates_pct` 를 읽는다.",
"kind": "doc"
}
]
},
@@ -1827,6 +1873,12 @@
"summary": "실무 집계에서 본 할증률. 참고이지 기본값이 아니다.",
"kind": "value"
},
{
"key": "original_tables",
"name_ko": "원문 표가 실린 자리",
"summary": "같은 값이 `coef` 의 `surcharge_mat` 에도 있다. ⚠ 두 벌이 아니다 — 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기다.",
"kind": "doc"
},
{
"key": "policy",
"name_ko": "방침",
@@ -2562,9 +2614,9 @@
{
"file_id": "revetment_sabang",
"path": "resources/data_masonry/revetment_sabang_2026-01-01.json",
"name_ko": "기슭막이 치수(사방)",
"summary": "독립 기슭막이의 높이·계획비탈·둑마루 두께·뒷채움을 한 자리에 둔 벌.",
"kind": "logic",
"name_ko": "기슭막이 치수(사방) — 참고 사례",
"summary": "사방기술교본 값에 설명 글이 섞인 벌. ⚠ 기초데이터가 아니다 — 표준값처럼 쓰지 말고 근거로만 본다(2026-09-16 사용자 판정).",
"kind": "reference",
"tables": [],
"value_groups": [
{
@@ -2596,9 +2648,9 @@
{
"file_id": "structure_unit_observed",
"path": "resources/data_structure_unit/structure_unit_observed_2026-01-01.json",
"name_ko": "구조물 관측 원단위",
"summary": "품셈에 표준 물량표가 없는 콘크리트 구조물을 실무 설계원본에서 뽑은 벌.",
"kind": "logic",
"name_ko": "구조물 관측 원단위 — 참고 사례",
"summary": "울진소광 **한 현장**을 관찰한 값이다. ⚠ 기초데이터가 아니다 — 규격이 다르면 안 맞고 표준도 아니다(2026-09-16 사용자 판정).",
"kind": "reference",
"tables": [
{
"key": "double_count_rules/rules",
@@ -6320,6 +6372,16 @@
"unit": "",
"visible": true
},
"duplicate_reason": {
"name_ko": "중복 사유",
"unit": "",
"visible": true
},
"duplicate_same_value": {
"name_ko": "값 같은 중복",
"unit": "",
"visible": true
},
"duration_bracket": {
"name_ko": "공사기간 구간",
"unit": "",
@@ -6470,6 +6532,11 @@
"unit": "",
"visible": true
},
"hidden_duplicate": {
"name_ko": "접힌 줄",
"unit": "",
"visible": false
},
"hours_per_day": {
"name_ko": "1일 근로시간",
"unit": "시간",
@@ -7479,6 +7546,10 @@
"name_ko": "값 단위",
"summary": "할증은 %다."
},
"coef::variables/surcharge_mat/used_value_at": {
"name_ko": "쓰는 값이 있는 자리",
"summary": "이 표는 원문 보관용이라 읽는 코드가 없다. 값은 `material_surcharge` 의 `rates_pct` 를 읽는다."
},
"formwork_reuse::reuse_ratio_pct": {
"name_ko": "사용횟수별 기준수량 비율",
"summary": "품셈 12-4 — 일위대가 재료비에 걸린다. B08 이 곱하면 이중계상이다."
@@ -7599,6 +7670,10 @@
"name_ko": "실무 관측",
"summary": "실무 집계에서 본 할증률. 참고이지 기본값이 아니다."
},
"material_surcharge::original_tables": {
"name_ko": "원문 표가 실린 자리",
"summary": "같은 값이 `coef` 의 `surcharge_mat` 에도 있다. ⚠ 두 벌이 아니다 — 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기다."
},
"oil::variables/oil_diesel": {
"name_ko": "경유 단가",
"summary": "전국평균 경유 값(원/L)."
@@ -6,8 +6,8 @@
"files": [
{
"file": "material_surcharge_2026-01-01.json",
"sha256": "30a1e11acb6f6bd52c72e0ff471c96f772917858306ea61f66ecbcb5df433c9f",
"size_bytes": 5087
"sha256": "1394a39be22ac0eb7476e4bc2b81c1e23c365a4ad5b915befe85d3f0f99023d5",
"size_bytes": 5344
}
]
}
@@ -1,6 +1,7 @@
{
"schema_version": "1.0",
"dataset_id": "material_surcharge",
"original_tables": "resources/data_cost_input_value/coef_2026.json → variables/surcharge_mat — 원문 표가 실린 자리. ⚠ 값이 겹치지만 이원화가 아니다: 저쪽은 원문 보관이고 읽어 쓰는 정본은 여기(rates_pct)다.",
"effective_date": "2026-01-01",
"source": {
"primary": {
+3 -1
View File
@@ -19,7 +19,9 @@ ROOT = Path(__file__).resolve().parents[2]
LABELS_PATH = ROOT / "resources" / "data_master_labels" / "labels_2026-01-01.json"
#: 브레인 갈래 나눔표(2026-09-15). 폴더 장부(_manifest)는 그 31 밖이라 따로 센다.
BRAIN_KIND_COUNTS = {"logic": 17, "base_value": 9, "byproduct": 4, "seed": 1}
#: 2026-09-16 사용자 판정 — `structure_unit_observed`(울진소광 한 현장 관찰값)와
#: `revetment_sabang`(교본값에 설명 글 섞임)은 기초데이터가 아니라 **참고 사례**다.
BRAIN_KIND_COUNTS = {"logic": 15, "base_value": 9, "byproduct": 4, "seed": 1, "reference": 2}
MANIFEST_PREFIX = "manifest_"
META_KEYS = {
+9 -1
View File
@@ -49,7 +49,15 @@ def test_갈래는_이름표_차례_파일_34_강우_캐시는_없음(client: Te
groups = _tree(client)["groups"]
assert [g["key"] for g in groups] == [k for k in LABELS["kinds"]]
counts = {g["key"]: len(g["files"]) for g in groups}
assert counts == {"logic": 17, "base_value": 9, "byproduct": 4, "fingerprint": 3, "seed": 1}
# 2026-09-16 사용자 판정 — 한 현장 관찰값·교본 설명 섞임 둘은 참고 사례로 옮겼다.
assert counts == {
"logic": 15,
"base_value": 9,
"byproduct": 4,
"reference": 2,
"fingerprint": 3,
"seed": 1,
}
assert {g["key"]: g["label"] for g in groups}["base_value"] == "기초값"
by_id = {f["file_id"]: f for f in LABELS["files"]}
for f in (f for g in groups for f in g["files"]):