From c12367cc333161c5326ed79b62358bf6de9f84b5 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 16:58:31 +0900 Subject: [PATCH 1/5] =?UTF-8?q?chore(data):=20=EC=A0=84=EC=88=98=20?= =?UTF-8?q?=EB=8C=80=EC=A1=B0=EA=B8=B0=C2=B7=EA=B2=B8=EC=9A=A9=20=EC=97=B0?= =?UTF-8?q?=EB=A3=8C=C2=B79020=20=EC=9D=B4=EC=96=B4=20=ED=91=9C=EB=A5=BC?= =?UTF-8?q?=20=EB=B0=9B=EC=95=84=20=EB=8B=A4=EC=8B=9C=20=EB=BD=91=EC=9D=8C?= =?UTF-8?q?=20=E2=80=94=20=EA=B1=B4=EC=84=A4=20=ED=98=95=ED=83=9C=20166=20?= =?UTF-8?q?=C2=B7=20=EB=B0=91=EC=88=98=20=EB=AF=B8=ED=8C=90=EB=8F=85=20?= =?UTF-8?q?=EA=B1=B4=EC=84=A4=202=C2=B7=EC=82=B0=EB=A6=BC=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **받아 다시 뽑은 결과** · 건설 형태 미판정 175 → **166** · 밑수 확보 **713** · 미확보 438(원문 부재 436 · **미판독 2**) · 산림 밑수 미확보 79(원문 부재 78 · **미판독 1**) · 품셈 원천 건설 표 2,273 → **2,274**(산림 476 그대로) · 기계 손료 611 → **620** · 연료 274 → **276** ⇒ 랩탑 서브가 9020 이어 표를 붙이고 랩탑 메인이 겸용 연료를 갈라 읽은 것이 그대로 들어옴 **장부 손질** · ⚠ 합치며 **내 갈래와 랩탑 메인의 옛 class·주인이 섞였음** — 「원문 부재」인데 주인이 랩탑 메인으로 적힌 일곱 줄을 ㉰ 로 되돌리고 주인을 뗌. 원문에 없는 것은 남이 고쳐도 안 풀림. · 랩탑 메인이 새로 올린 「손료보정」 세 줄에 갈래·사유·주인 적음 — 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉은 자리(「손료보정 수 자리 가름」 과 한 뿌리) · 기계 장부에서 **저절로 빠진 것** — 9020 이어 표 일곱 · 겸용 연료 둘 · 손료 계수 칸 없는 표 둘 ⇒ 지금 어긋남: 공종 마스터 **22** · 기초데이터 **1** · 기초단가 **23**(잣대 못 알아봄 16 · 원문 부재 7) Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- .../data_work_item_master/_manifest.json | 4 +- .../_manifest_const.json | 4 +- .../const_work_item_master_2026-01-01.json | 2 +- .../work_item_master_2026-01-01.json | 2 +- .../fixtures/base_prices_source_known.json | 62 +++++++++---------- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/resources/data_work_item_master/_manifest.json b/resources/data_work_item_master/_manifest.json index 30ff4900..1b5ad8bb 100644 --- a/resources/data_work_item_master/_manifest.json +++ b/resources/data_work_item_master/_manifest.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", "dataset_id": "data_work_item_master_manifest", - "generated_at": "2026-09-18T14:37:31+09:00", + "generated_at": "2026-09-18T16:52:57+09:00", "built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py", "source": { "dataset_id": "pum_forest", @@ -12,7 +12,7 @@ "files": [ { "file": "work_item_master_2026-01-01.json", - "sha256": "eba4d71093f730296ff74de519949e8bfb573fea129b45b9be31b763db20307a", + "sha256": "bc1e5b301f79247bf44bb3dfa51e409a22e059771eba53670a599753a235e1b4", "size_bytes": 1095122 }, { diff --git a/resources/data_work_item_master/_manifest_const.json b/resources/data_work_item_master/_manifest_const.json index cde09ad8..6ec7fe0e 100644 --- a/resources/data_work_item_master/_manifest_const.json +++ b/resources/data_work_item_master/_manifest_const.json @@ -1,7 +1,7 @@ { "schema_version": "1.0", "dataset_id": "data_work_item_master_manifest", - "generated_at": "2026-09-18T14:38:23+09:00", + "generated_at": "2026-09-18T16:54:24+09:00", "built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py", "source": { "dataset_id": "pum_const", @@ -12,7 +12,7 @@ "files": [ { "file": "const_work_item_master_2026-01-01.json", - "sha256": "717ed8edf3aa8f0ecf38634f28ae0ed8c7f47bffbe3a4ede8af6a279396d9933", + "sha256": "7117fdb70e26e65671002dad427f155ba0782e02ad10ba9c2f4729d5c22f9c4e", "size_bytes": 4730739 }, { diff --git a/resources/data_work_item_master/const_work_item_master_2026-01-01.json b/resources/data_work_item_master/const_work_item_master_2026-01-01.json index bbfb254b..c88a252a 100644 --- a/resources/data_work_item_master/const_work_item_master_2026-01-01.json +++ b/resources/data_work_item_master/const_work_item_master_2026-01-01.json @@ -4,7 +4,7 @@ "effective_date": "2026-01-01", "pum_edition": "2026-01-01", "toc_edition": "2026-01-01", - "generated_at": "2026-09-18T14:38:23+09:00", + "generated_at": "2026-09-18T16:54:24+09:00", "dataset_version": { "dataset_id": "pum_const", "effective_date": "2026-01-01", diff --git a/resources/data_work_item_master/work_item_master_2026-01-01.json b/resources/data_work_item_master/work_item_master_2026-01-01.json index 3ab2d533..74adb542 100644 --- a/resources/data_work_item_master/work_item_master_2026-01-01.json +++ b/resources/data_work_item_master/work_item_master_2026-01-01.json @@ -4,7 +4,7 @@ "effective_date": "2026-01-01", "pum_edition": "2026-01-01", "toc_edition": "산림청고시제2025-82호", - "generated_at": "2026-09-18T14:37:31+09:00", + "generated_at": "2026-09-18T16:52:57+09:00", "dataset_version": { "dataset_id": "pum_forest", "effective_date": "2026-01-01", diff --git a/resources/tester/fixtures/base_prices_source_known.json b/resources/tester/fixtures/base_prices_source_known.json index e04c0061..145d5bd3 100644 --- a/resources/tester/fixtures/base_prices_source_known.json +++ b/resources/tester/fixtures/base_prices_source_known.json @@ -55,19 +55,31 @@ "source": "불도저(19톤이상제외)", "data": "2510", "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림" + "class": "㉯ 남이 고쳐야 풀림", + "갈래": "잣대 못 알아봄", + "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", + "owner": "랩탑 메인", + "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." }, "손료보정 crawler_excavator_or_loader": { "source": "굴착기(무한궤도)및로더(무한궤도)", "data": "2010", "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림" + "class": "㉯ 남이 고쳐야 풀림", + "갈래": "잣대 못 알아봄", + "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", + "owner": "랩탑 메인", + "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." }, "손료보정 dump_truck": { "source": "덤프트럭", "data": "2510", "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림" + "class": "㉯ 남이 고쳐야 풀림", + "갈래": "잣대 못 알아봄", + "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", + "owner": "랩탑 메인", + "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." }, "연료 7993-0020": { "source": null, @@ -167,31 +179,25 @@ "운전사 기종별 판단": { "what": 121, "why": "기종→운전사 구분(explicit_mappings)은 사람 판단 — 원문 8-1-3 5호는 기종 이름 글만 있음", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "원문 8-1-3 5호는 기종 이름 글만 두고 운전사 구분을 안 적음 — 기종→운전사 짝(`explicit_mappings`)은 사람이 정한 것. 원문에 견줄 것이 없음.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "원문 8-1-3 5호는 기종 이름 글만 두고 운전사 구분을 안 적음 — 기종→운전사 짝(`explicit_mappings`)은 사람이 정한 것. 원문에 견줄 것이 없음." } }, "material_blind": { "같은 때 공시 20696249": { "what": 2, "why": "같은 공시 일시에 값 실린 공시가 둘 — 원천이 어느 것이 정본인지 안 알려 줌 · 자료는 그중 하나와 같음", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "같은 공시 일시에 값 실린 공시가 둘인데 **원천이 어느 것을 정본으로 보는지 안 알려 줌** — 자료는 그중 하나와 같음. 어느 것을 취할지 정해야 닫힘.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "같은 공시 일시에 값 실린 공시가 둘인데 **원천이 어느 것을 정본으로 보는지 안 알려 줌** — 자료는 그중 하나와 같음. 어느 것을 취할지 정해야 닫힘." }, "같은 때 공시 20696250": { "what": 2, "why": "같은 공시 일시에 값 실린 공시가 둘 — 원천이 어느 것이 정본인지 안 알려 줌 · 자료는 그중 하나와 같음", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "위와 한 자리.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "위와 한 자리." }, "원천 없는 묶음": { "what": [ @@ -200,11 +206,9 @@ "asphalt_concrete" ], "why": "철근·레미콘·아스콘은 종합쇼핑몰 원천이 저장소에 없음 — 값 못 봄", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "철근·레미콘·아스콘은 종합쇼핑몰 원천이 저장소에 없어 값을 볼 수 없음 — 원천을 들여올지 정해야 닫힘.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "철근·레미콘·아스콘은 종합쇼핑몰 원천이 저장소에 없어 값을 볼 수 없음 — 원천을 들여올지 정해야 닫힘." } }, "oil_blind": {}, @@ -212,29 +216,23 @@ "안 잰 칸 rate_environment.forest_road_selection_status": { "what": "pending", "why": "임도 공종 선택 미결 표시 — 사용자 협의 몫", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "임도 공종 선택 미결 표시 — 사용자 협의로 닫을 자리.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "임도 공종 선택 미결 표시 — 사용자 협의로 닫을 자리." }, "안 잰 칸 rate_environment.minimum_estimated_amount_krw": { "what": 100000000, "why": "xlsx 환경보전비 칸에 1억 기준이 없음(1억은 퇴직공제부금 칸) — 근거 원문이 sources 에 없어 못 봄", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "xlsx 환경보전비 칸에 1억 기준이 없음(1억은 퇴직공제부금 칸) — 근거 원문이 `sources` 에 없어 볼 수 없음. 근거를 들여올지 정해야 닫힘.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "xlsx 환경보전비 칸에 1억 기준이 없음(1억은 퇴직공제부금 칸) — 근거 원문이 `sources` 에 없어 볼 수 없음. 근거를 들여올지 정해야 닫힘." }, "안 잰 칸 rate_performance_guarantee_fee.typical_forest_road_applicability": { "what": "not_applicable", "why": "임도 적용 판단 — 원문 칸 아님", - "class": "㉯ 남이 고쳐야 풀림", + "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "임도에 적용되는지 판단 — 원문 칸이 아님.", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림" + "class_why": "임도에 적용되는지 판단 — 원문 칸이 아님." } }, "_할일_아님": { @@ -556,7 +554,7 @@ "센 날": "2026-09-18", "셈": { "원문 부재 / ㉰": 7, - "잣대 못 알아봄 / ㉯": 17 + "잣대 못 알아봄 / ㉯": 16 }, "잣대": "두 갈래로 가름 — **원문 부재**: 값이 원문·원천에 없거나 원문 밖 말이라 채울 것이 없음 · **잣대 못 알아봄**: 값은 원문에 있는데 전사·읽기가 못 가름 ⇒ 고치면 풀림. ㉮ 영영 할 일 아님 · ㉯ 남이 고쳐야 풀림 · ㉰ 사용자·브레인 판단.", "할 일 아님으로 뺀 줄": 34 From fd6865c19afe78f6464aa490425508e0581d55d8 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 17:04:46 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix(data):=20=EC=88=AB=EC=9E=90=EB=A1=9C=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=ED=95=98=EB=8A=94=20=EA=B8=B0=EC=A2=85=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=84=20=EB=B2=84=EB=A6=AC=EB=8D=98=20?= =?UTF-8?q?=EC=9E=A3=EB=8C=80=20=EA=B3=A0=EC=B9=A8=20=C2=B7=208-1-7=20?= =?UTF-8?q?=EC=86=90=EB=A3=8C=EB=B3=B4=EC=A0=95=EC=9D=84=20=EC=A0=9C=20?= =?UTF-8?q?=ED=91=9C=EC=97=90=EC=84=9C=20=EC=9D=BD=EC=9D=8C=20=E2=80=94=20?= =?UTF-8?q?=EA=B8=B0=EC=B4=88=EB=8B=A8=EA=B0=80=20=EC=9E=A3=EB=8C=80=2016?= =?UTF-8?q?=20=E2=86=92=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **① 기종 이름 — `(8201) 3D GNSS 머신 가이던스(굴착기용)`** 추출기가 **첫 낱자가 숫자면 쪽번호로 보고 버리던** 탓에 8201 이름을 못 찾고 **옛 벌의 뭉개진 글**을 이어받고 있었음(`배관파이프시 간 당(10-7)분류번호규 격7995-0050…`). 낱자가 하나도 없는 토막만 버리게 고침 — 옛 벌에서 이어받은 이름 7 → **0** · 이름 바로잡힌 줄 1(값은 안 움직임). ⚠ `_build_mach.py` 는 랩탑 메인이 지은 것 — 한 줄 잣대만 고쳤음. **② 8-1-7 손료보정 — 원문이 제 표로 고쳐졌음** 전엔 글로 뭉개져 `덤프트럭2510` 처럼 붙어 있어 「25·10 인지 2·510 인지 못 가름」으로 세고 있었음. 이제 `| 덤프트럭 | 25 | 10 |` 이라 **칸에서 바로** 읽음 — 기종 글은 원문이 낱자 사이에 빈칸을 두므로 (`불도저( 1 9 톤이상 제외)`) 빈칸을 지워 맞댐. 네 줄이 한꺼번에 풀림(보정 셋 + 수 자리 가름). **③ 이름 없는 기종을 세는 자리** — 8-3 에 `(코드) 이름` 머리글이 없어 **양쪽이 다 비어 조용히 지나가는** 자리를 세게 함. 지금은 **0** — 8202~8204 도 머리글이 [주] 줄에 섞여 있어 둘 다 읽고 있음. ⇒ 기초단가 어긋남 23 → **17**(잣대 못 알아봄 16 → **10** · 원문 부재 7). 남은 잣대 10 은 다 랩탑 서브 PDF 몫 — 규격 빈칸 일곱(원문이 기종 이름을 여러 줄로 쪼갬) · 양수기 7993-0020 셋(규격이 주연료 칸에 밀림). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- .../data_cost_input_value/_build_mach.py | 5 +- .../data_cost_input_value/mach_base_2026.json | 6 +- .../fixtures/base_prices_source_known.json | 61 +------------------ .../tester/test_base_prices_source_match.py | 31 +++++++--- 4 files changed, 31 insertions(+), 72 deletions(-) diff --git a/resources/data_cost_input_value/_build_mach.py b/resources/data_cost_input_value/_build_mach.py index 01847b15..74926de0 100644 --- a/resources/data_cost_input_value/_build_mach.py +++ b/resources/data_cost_input_value/_build_mach.py @@ -123,7 +123,10 @@ def names_in(lines: list[str]) -> dict[str, str]: continue for m in _NAME_AT.finditer(line): name = m.group(2).strip(" .·") - if name and not name[0].isdigit(): + # ⚠ 숫자로 시작하는 이름도 있다 — `(8201) 3D GNSS 머신 가이던스(굴착기용)`. + # 첫 낱자가 숫자면 버리던 잣대가 그것을 쪽번호로 보고 내버려, 옛 벌의 뭉개진 글을 + # 이어받고 있었다(2026-09-18). 낱자가 하나도 없는 토막만 버린다. + if name and re.search(r"[가-힣A-Za-z]", name): found.setdefault(m.group(1), re.sub(r"\s+", " ", name)) return found diff --git a/resources/data_cost_input_value/mach_base_2026.json b/resources/data_cost_input_value/mach_base_2026.json index e979cbe7..f219ed1c 100644 --- a/resources/data_cost_input_value/mach_base_2026.json +++ b/resources/data_cost_input_value/mach_base_2026.json @@ -2,7 +2,7 @@ "schema_version": "1.0", "dataset_id": "mach_base", "effective_date": "2026-01-01", - "generated_at": "2026-09-18T14:37:18+09:00", + "generated_at": "2026-09-18T17:02:43+09:00", "sources": [ { "path": "resources/knowledge/original/원가계산/건설공사_표준품셈/01_공통부문/제8장_건설기계.md", @@ -3177,7 +3177,7 @@ }, { "machine_code": "8201-0100", - "machine_name": "", + "machine_name": "3D GNSS 머신 가이던스(굴착기용)", "price_thousand_krw": 55000, "specification": "3D GNSS MG" }, @@ -11565,7 +11565,7 @@ }, { "machine_code": "8201-0100", - "machine_name": "배관파이프시 간 당(10-7)분류번호규 격7995-0050ø50-2.6m5,0008-3-9 [80]스마트 건설장비(8201) 3D GNSS 머신 가이던스(굴착기용)", + "machine_name": "3D GNSS 머신 가이던스(굴착기용)", "specification": "3D GNSS MG", "loss_coefficient_per_hour": 0.00039299999999999996, "depreciation_coefficient_1e_minus_7": 1800, diff --git a/resources/tester/fixtures/base_prices_source_known.json b/resources/tester/fixtures/base_prices_source_known.json index 145d5bd3..170238c1 100644 --- a/resources/tester/fixtures/base_prices_source_known.json +++ b/resources/tester/fixtures/base_prices_source_known.json @@ -11,16 +11,6 @@ ], "labor": {}, "machine": { - "가격 8201-0100 machine_name": { - "source": "3D GNSS 머신 가이던스(굴착기용)", - "data": "", - "why": "자료 이름이 빔 — 원문 손료표 머리 `(코드) 이름` 엔 이름 있음", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림", - "갈래": "잣대 못 알아봄", - "class_why": "제8장 8-3 (8201) 손료표 머리가 글로 뭉개져 기종 이름이 표 밖 글줄에 섞였음 — PDF 대조로 표 머리를 되살려 줄 것. 되살리면 추출기·시험이 저절로 읽음." - }, "셈 연료 원문에 없는 자료 줄": { "source": 0, "data": 1, @@ -41,46 +31,6 @@ "갈래": "잣대 못 알아봄", "class_why": "위 7993-0020 과 한 자리 — 그 줄이 고쳐지면 셈도 맞음." }, - "손료 8201-0100 machine_name": { - "source": "3D GNSS 머신 가이던스(굴착기용)", - "data": "배관파이프시 간 당(10-7)분류번호규 격7995-0050ø50-2.6m5,0008-3-9 [80]스마트 건설장비(8201) 3D GNSS 머신 가이던스(굴착기용)", - "why": "자료 이름 칸에 원문 뭉개진 손료 글이 통째로 들어감 — 자료 이름 틀림", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림", - "갈래": "잣대 못 알아봄", - "class_why": "위와 한 자리 — 뭉개진 글이 자료 이름 칸에 통째로 들어갔음." - }, - "손료보정 bulldozer_under_19_ton": { - "source": "불도저(19톤이상제외)", - "data": "2510", - "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림", - "갈래": "잣대 못 알아봄", - "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", - "owner": "랩탑 메인", - "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." - }, - "손료보정 crawler_excavator_or_loader": { - "source": "굴착기(무한궤도)및로더(무한궤도)", - "data": "2010", - "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림", - "갈래": "잣대 못 알아봄", - "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", - "owner": "랩탑 메인", - "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." - }, - "손료보정 dump_truck": { - "source": "덤프트럭", - "data": "2510", - "why": "원문 8-1-7 가산비율 표가 글로 뭉개져 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 못 가름(같은 자리를 「손료보정 수 자리 가름」으로 이미 적어 둠). md 가 풀리면 저절로 맞음", - "class": "㉯ 남이 고쳐야 풀림", - "갈래": "잣대 못 알아봄", - "class_why": "원문 8-1-7 가산비율 표가 **글로 뭉개져** 기종 이름 칸에 수(`2510`)가 들어앉음 — 25·10 인지 2·510 인지 가를 수 없음. 값은 원문에 있으나 꼴이 뭉개져 못 읽는 자리(같은 뿌리를 「손료보정 수 자리 가름」 으로도 셈).", - "owner": "랩탑 메인", - "owner_ask": "8-1-7 가산비율 표가 글로 뭉개진 자리 — 기종 이름과 두 수(암석작업·전석섞인토사)를 갈라 줄 것. `손료보정 수 자리 가름` 과 한 자리라 함께 풀림." - }, "연료 7993-0020": { "source": null, "data": { @@ -167,15 +117,6 @@ "owner": "랩탑 서브", "owner_ask": "제8장 8-3 (7430)·(7431) 윈치 · (7811)·(7812) 엔진 · (9030) 예선 표 — PDF 에서 「기종」 칸이 한 칸에 어떻게 적혀 있는지 짚어 줄 것(「수동 싱글드럼」 처럼 한 칸인지, 줄마다 다른 이름인지). 그것이 갈리면 자료의 이어받기가 맞는지 곧 판가름남." }, - "손료보정 수 자리 가름": { - "what": "뭉개진 글의 이어 붙은 수(2510)를 통째로 맞댐", - "why": "8-1-7 가산비율 표가 글로 뭉개져 `2510` 처럼 붙음 — 25·10 인지 2·510 인지 못 가름", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림", - "갈래": "잣대 못 알아봄", - "class_why": "8-1-7 가산비율 표가 글로 뭉개져 `2510` 처럼 붙었음 — 25·10 인지 2·510 인지 PDF 로 갈라 줄 것." - }, "운전사 기종별 판단": { "what": 121, "why": "기종→운전사 구분(explicit_mappings)은 사람 판단 — 원문 8-1-3 5호는 기종 이름 글만 있음", @@ -554,7 +495,7 @@ "센 날": "2026-09-18", "셈": { "원문 부재 / ㉰": 7, - "잣대 못 알아봄 / ㉯": 16 + "잣대 못 알아봄 / ㉯": 10 }, "잣대": "두 갈래로 가름 — **원문 부재**: 값이 원문·원천에 없거나 원문 밖 말이라 채울 것이 없음 · **잣대 못 알아봄**: 값은 원문에 있는데 전사·읽기가 못 가름 ⇒ 고치면 풀림. ㉮ 영영 할 일 아님 · ㉯ 남이 고쳐야 풀림 · ㉰ 사용자·브레인 판단.", "할 일 아님으로 뺀 줄": 34 diff --git a/resources/tester/test_base_prices_source_match.py b/resources/tester/test_base_prices_source_match.py index 788a4185..e4669890 100644 --- a/resources/tester/test_base_prices_source_match.py +++ b/resources/tester/test_base_prices_source_match.py @@ -343,7 +343,8 @@ def read_machine(path: Path) -> dict: return out -#: 손료보정 표는 글로 뭉개짐 — 기종 글 바로 뒤에 `암석작업` `전석섞인토사` 두 수가 붙어 있음(`덤프트럭2510`). +#: 8-1-7 손료보정 표의 기종 글 — 원문이 낱자 사이에 빈칸을 두므로(`불도저( 1 9 톤이상 제외)`) **빈칸을 지워** 맞댄다. +#: 2026-09-18 md 가 제 표로 고쳐져 두 수(암석작업·전석섞인토사)를 **칸에서 바로** 읽는다(전엔 `덤프트럭2510` 처럼 글로 뭉개져 있었다). ROCK = {"bulldozer_under_19_ton": "불도저(19톤이상제외)", "crawler_excavator_or_loader": "굴착기(무한궤도)및로더(무한궤도)", "dump_truck": "덤프트럭"} # fmt: skip @@ -379,6 +380,11 @@ def check_machine(src: dict, bad: dict, blind: dict) -> dict: counts[f"{label} 코드 수"] = (len(rows), len(by_code)) counts[f"{label} 원문에 없는 자료 줄"] = (0, len(set(by_code) - set(rows) - unread)) _unchecked(blind, var, records, {"machine_code", "machine_name", *fields}) + # 원문 8-3 에 `(코드) 이름` 머리글이 아예 없어 **이름이 빈** 기종 — 양쪽이 다 비어 조용히 지나간다. + # 표는 있는데 이름만 없는 자리라 세어 둔다(md 에 머리글이 붙으면 저절로 빠짐). + for code, rec in sorted({r["machine_code"]: r for r in v["mach_loss_coef"]["records"]}.items()): + if not rec.get("machine_name") and source["names"].get(code[:4]) is None: + blind[f"기종 이름 없는 머리글 {code[:4]}"] = {"what": code} # 원문이 규격 칸을 비워 둔 자리에 **자료가 앞 줄 값을 이어받아 채운** 줄 — 원문에 없는 글이라 사람이 볼 자리. loss_by_code = {r["machine_code"]: r for r in v["mach_loss_coef"]["records"]} for code in sorted(source.get("spec_blank", ())): @@ -412,15 +418,24 @@ def check_machine(src: dict, bad: dict, blind: dict) -> dict: ) text = _t("".join(source["lines"])) + rock_rows = {} # 기종 글(빈칸 지움) → (암석작업, 전석섞인토사) + for t in md_tables(source["lines"]): + if [_t(h) for h in t["headers"]][:2] != ["기종", "가산비율"]: + continue + for r in t["rows"]: + try: + rock_rows[_t(r[0])] = (_num(r[1]), _num(r[2])) + except ValueError: # 머리 곁줄(`암석작업(연암…)` · `전석섞인토사`) + continue for rule in v["mach_rock_adj"]["rules"]: - group, pair = rule["machine_group"], f"{rule['rock_work']}{rule['boulder_mixed_soil']}" + group = rule["machine_group"] + pair = (rule["rock_work"], rule["boulder_mixed_soil"]) if group in ROCK: - ok = f"{ROCK[group]}{pair}" in text - else: - ok = pair == "00" and "불도저(19톤이상)의경우는보정하지않는다" in text - if not ok: - bad[f"손료보정 {group}"] = {"source": ROCK.get(group), "data": pair} - blind["손료보정 수 자리 가름"] = {"what": "뭉개진 글의 이어 붙은 수(2510)를 통째로 맞댐"} + got = rock_rows.get(ROCK[group]) + else: # 「불도저(19톤이상)은 보정하지 않는다」 — 표에 줄이 없고 [주]①이 0 을 말한다 + got = (0, 0) if "불도저(19톤이상)의경우는보정하지않는다" in text else None + if got != pair: + bad[f"손료보정 {group}"] = {"source": got, "data": list(pair)} _unchecked(blind, "mach_rock_adj.rules", v["mach_rock_adj"]["rules"], {"machine_group", "rock_work", "boulder_mixed_soil"}) # fmt: skip return counts From 61f08d33a6c68811c3d64e543c9ed103aeab71ee Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 17:06:50 +0900 Subject: [PATCH 3/5] =?UTF-8?q?chore(tester):=20=EC=96=91=EC=88=98?= =?UTF-8?q?=EA=B8=B0=207993-0020=20=EC=84=B8=20=EC=A4=84=20=E2=80=94=20?= =?UTF-8?q?=EC=9B=90=EB=AC=B8=20=EC=AA=BD=EC=9D=80=20=EB=8B=AB=EA=B3=A0=20?= =?UTF-8?q?=E3=80=8C=EC=9E=90=EB=A3=8C=20=EC=AA=BD=E3=80=8D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=AC=EB=B6=84=ED=95=B4=20=EC=A0=81=EC=9D=8C(?= =?UTF-8?q?=EC=9E=A3=EB=8C=80=2010=20=E2=86=92=207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 랩탑 서브가 PDF 로 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고(cae43718) md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`) ⇒ **원문에 기름 값이 없음.** 남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**임(다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길 둘을 사유에 적어 둠 — ㉠ 원문에 없으니 비움 · ㉡ 사람이 정해 넣는 자리로 남기고 표시를 달기. 어느 쪽인지는 판정 자리라 그대로 둠(지어 채우지 않음). ⇒ 갈래를 「잣대 못 알아봄 · 랩탑 서브」에서 **「원문 부재 · ㉰ 판정」**으로 옮김. 기초단가 17 — 잣대 못 알아봄 **7**(규격 빈칸 일곱, 랩탑 서브 B17) · 원문 부재 10(㉰). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- .../fixtures/base_prices_source_known.json | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/resources/tester/fixtures/base_prices_source_known.json b/resources/tester/fixtures/base_prices_source_known.json index 170238c1..a6db28e6 100644 --- a/resources/tester/fixtures/base_prices_source_known.json +++ b/resources/tester/fixtures/base_prices_source_known.json @@ -14,22 +14,18 @@ "셈 연료 원문에 없는 자료 줄": { "source": 0, "data": 1, - "why": "원문이 규격을 연료 칸에 밀어 적은 양수기 7993-0020 — 사람이 맞춘 1.3ℓ(휘발유)를 옛 벌에서 이어받음(원문 값 그대로) · 이 시험 읽기는 그 줄을 못 따라감", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 서브", - "owner_ask": "위와 같음.", - "갈래": "잣대 못 알아봄", - "class_why": "위와 같음." + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "class": "㉰ 사용자·브레인 판단", + "갈래": "원문 부재", + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." }, "셈 연료 코드 수": { "source": 275, "data": 276, - "why": "원문이 규격을 연료 칸에 밀어 적은 양수기 7993-0020 — 사람이 맞춘 1.3ℓ(휘발유)를 옛 벌에서 이어받음(원문 값 그대로) · 이 시험 읽기는 그 줄을 못 따라감", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 서브", - "owner_ask": "위 7993-0020 과 한 자리 — 그 줄이 고쳐지면 셈도 맞음.", - "갈래": "잣대 못 알아봄", - "class_why": "위 7993-0020 과 한 자리 — 그 줄이 고쳐지면 셈도 맞음." + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "class": "㉰ 사용자·브레인 판단", + "갈래": "원문 부재", + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." }, "연료 7993-0020": { "source": null, @@ -41,12 +37,10 @@ "parse_method": "verified_source_row_alignment", "specification": "1.49㎾" }, - "why": "원문이 규격을 연료 칸에 밀어 적은 양수기 7993-0020 — 사람이 맞춘 1.3ℓ(휘발유)를 옛 벌에서 이어받음(원문 값 그대로) · 이 시험 읽기는 그 줄을 못 따라감", - "class": "㉯ 남이 고쳐야 풀림", - "owner": "랩탑 서브", - "owner_ask": "8-4 양수기 7993-0020 주연료 칸에 규격(1.49㎾)이 밀려 들어갔음 — PDF 대조로 휘발유 1.3ℓ 를 제자리에 적어 줄 것.", - "갈래": "잣대 못 알아봄", - "class_why": "8-4 양수기 7993-0020 주연료 칸에 규격(1.49㎾)이 밀려 들어갔음 — PDF 대조로 휘발유 1.3ℓ 를 제자리에 적어 줄 것." + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "class": "㉰ 사용자·브레인 판단", + "갈래": "원문 부재", + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." } }, "material": {}, @@ -494,8 +488,8 @@ "_갈래": { "센 날": "2026-09-18", "셈": { - "원문 부재 / ㉰": 7, - "잣대 못 알아봄 / ㉯": 10 + "원문 부재 / ㉰": 10, + "잣대 못 알아봄 / ㉯": 7 }, "잣대": "두 갈래로 가름 — **원문 부재**: 값이 원문·원천에 없거나 원문 밖 말이라 채울 것이 없음 · **잣대 못 알아봄**: 값은 원문에 있는데 전사·읽기가 못 가름 ⇒ 고치면 풀림. ㉮ 영영 할 일 아님 · ㉯ 남이 고쳐야 풀림 · ㉰ 사용자·브레인 판단.", "할 일 아님으로 뺀 줄": 34 From 8ddfcd6e5754467f5fad5f0d2e73f5f4b3d85712 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 17:08:24 +0900 Subject: [PATCH 4/5] =?UTF-8?q?chore(tester):=20=EC=96=91=EC=88=98?= =?UTF-8?q?=EA=B8=B0=207993-0020=20=E2=80=94=20=E3=80=8C=EB=82=A8=EA=B9=80?= =?UTF-8?q?=E3=80=8D=EC=9C=BC=EB=A1=9C=20=EC=9E=A0=EC=A0=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=ED=95=98=EA=B3=A0=20=ED=91=9C=EC=8B=9C=EB=A5=BC=20?= =?UTF-8?q?=EB=8B=AE(=EC=A7=80=EC=9A=B0=EC=A7=80=20=EC=95=8A=EC=9D=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브레인 B28 — 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라 (계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** · 세 줄에 `표시`(「원문 부재 · 옛 벌 이어받음 · 사람 확인 필요」)와 `잠정`(「남김 — 사용자 판단 목록 일곱째」)을 붙임 · 비울지 사람값 자리로 굳힐지는 사용자 회신 뒤 확정 · ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것** · 메모 칸(`_MEMO_FIELDS`)에 `표시`·`잠정` 을 더해 맞대기에서 뺌 — 사람이 적은 글이라 어긋남 판정에 안 씀 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- .../fixtures/base_prices_source_known.json | 18 ++++++++++++------ .../test_work_item_master_source_match.py | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/tester/fixtures/base_prices_source_known.json b/resources/tester/fixtures/base_prices_source_known.json index a6db28e6..792897b1 100644 --- a/resources/tester/fixtures/base_prices_source_known.json +++ b/resources/tester/fixtures/base_prices_source_known.json @@ -14,18 +14,22 @@ "셈 연료 원문에 없는 자료 줄": { "source": 0, "data": 1, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", + "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", + "잠정": "남김 — 사용자 판단 목록 일곱째" }, "셈 연료 코드 수": { "source": 275, "data": 276, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", + "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", + "잠정": "남김 — 사용자 판단 목록 일곱째" }, "연료 7993-0020": { "source": null, @@ -37,10 +41,12 @@ "parse_method": "verified_source_row_alignment", "specification": "1.49㎾" }, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.", + "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", "class": "㉰ 사용자·브레인 판단", "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음." + "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", + "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", + "잠정": "남김 — 사용자 판단 목록 일곱째" } }, "material": {}, diff --git a/resources/tester/test_work_item_master_source_match.py b/resources/tester/test_work_item_master_source_match.py index 3647598a..0f9a7476 100644 --- a/resources/tester/test_work_item_master_source_match.py +++ b/resources/tester/test_work_item_master_source_match.py @@ -374,7 +374,7 @@ def load_known() -> dict[str, dict]: #: 비교에서 뺄 칸 — **사람이 적은 메모**다. 자료가 아니라 설명이라 어긋남 판정에 안 쓴다. #: `class`·`class_why` 는 2026-09-18 에 붙인 갈래(㉮ 영영 아님 · ㉯ 남의 몫 · ㉰ 사용자 판단). -_MEMO_FIELDS = ("why", "class", "class_why", "was", "owner", "owner_ask", "갈래") +_MEMO_FIELDS = ("why", "class", "class_why", "was", "owner", "owner_ask", "갈래", "표시", "잠정") def _without_why(entry: dict) -> dict: From 184865cec929bf6e96964bd06d98ae06c9a62707 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 18 Sep 2026 17:27:00 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix(data):=20=EC=96=91=EC=88=98=EA=B8=B0=20?= =?UTF-8?q?7993-0020=20=ED=9C=98=EB=B0=9C=EC=9C=A0=201.3=20=EC=9D=80=20?= =?UTF-8?q?=EC=9D=B4=EC=9B=83=20=EC=A4=84=207992=20=EA=B2=83=20=E2=80=94?= =?UTF-8?q?=20=EC=98=A4=EA=B7=80=EC=86=8D=20=EB=B0=94=EB=A1=9C=EC=9E=A1?= =?UTF-8?q?=EC=95=84=20=EC=96=B4=EA=B8=8B=EB=82=A8=20=EC=85=8B=20=EB=8B=AB?= =?UTF-8?q?=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브레인 B30 원문 규명 — PDF 340쪽 주연료표의 「휘발유1.3」은 **바로 윗줄 7992(모르타르 믹서)** 것이고 양수기 줄은 전력 1.49㎾ 뿐이었음. 옛 추출이 **이웃 줄 값을 물려받은 자리 틀림**이었음 (「원문 부재」가 아니라 **이웃 줄 오귀속**). 7992 쪽 휘발유 1.3 은 이미 갈라 들어가 있음. · `mach_base_2026.json` 의 양수기 연료 줄을 지우고 다시 뽑음 — 연료 276 → **275** ⚠ 이어받기는 **옛 벌을 보고 되살리므로** 한 번 지워야 영영 안 돌아옴(`이어받음 {'fuel': 1}` → **0**) · 장부에서 세 줄이 닫힘(연료 7993-0020 · 셈 연료 코드 수 · 셈 연료 원문에 없는 자료 줄) — `_갈래.닫힌 자리` 에 규명·처리를 남겨 뒀음 · 딸려 빠진 줄 하나 — 「안 잰 칸 mach_fuel_rate.parse_method」(그 칸을 가진 줄이 그것뿐이었음) ⇒ 기초단가 어긋남 17 → **14**(잣대 못 알아봄 7 · 원문 부재 7) · 할 일 아님 34 → 33 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01QsGw1Dz9HmhuAxGisxmDPF --- .../data_cost_input_value/mach_base_2026.json | 8 --- .../fixtures/base_prices_source_known.json | 64 ++++--------------- 2 files changed, 12 insertions(+), 60 deletions(-) diff --git a/resources/data_cost_input_value/mach_base_2026.json b/resources/data_cost_input_value/mach_base_2026.json index f219ed1c..b7c12eac 100644 --- a/resources/data_cost_input_value/mach_base_2026.json +++ b/resources/data_cost_input_value/mach_base_2026.json @@ -15234,14 +15234,6 @@ "misc_material_percent_of_fuel": 2, "specification": "0.3㎥" }, - { - "machine_code": "7993-0020", - "machine_name": "양수기", - "fuel_type": "gasoline", - "fuel_rate_l_per_hour": 1.3, - "parse_method": "verified_source_row_alignment", - "specification": "1.49㎾" - }, { "machine_code": "7994-0050", "machine_name": "POWER TLOWEL", diff --git a/resources/tester/fixtures/base_prices_source_known.json b/resources/tester/fixtures/base_prices_source_known.json index 792897b1..be2c8d16 100644 --- a/resources/tester/fixtures/base_prices_source_known.json +++ b/resources/tester/fixtures/base_prices_source_known.json @@ -10,45 +10,7 @@ "why: 사람이 적은 까닭 — 시험은 맞대기에서 뺌." ], "labor": {}, - "machine": { - "셈 연료 원문에 없는 자료 줄": { - "source": 0, - "data": 1, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "class": "㉰ 사용자·브레인 판단", - "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", - "잠정": "남김 — 사용자 판단 목록 일곱째" - }, - "셈 연료 코드 수": { - "source": 275, - "data": 276, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "class": "㉰ 사용자·브레인 판단", - "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", - "잠정": "남김 — 사용자 판단 목록 일곱째" - }, - "연료 7993-0020": { - "source": null, - "data": { - "machine_code": "7993-0020", - "machine_name": "양수기", - "fuel_type": "gasoline", - "fuel_rate_l_per_hour": 1.3, - "parse_method": "verified_source_row_alignment", - "specification": "1.49㎾" - }, - "why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "class": "㉰ 사용자·브레인 판단", - "갈래": "원문 부재", - "class_why": "⭐ **원문 쪽은 닫힘** — 랩탑 서브가 PDF 를 보고(cae43718) 「원문이 규격·주연료 두 칸에 같은 ㎾ 를 적는 자리」로 판정했고, md 도 그대로임(`| 7993-0020 | 양수기 | 1.49㎾ | 1.49㎾ | - | - |`). ⇒ **원문에 기름 값(리터)이 없음.**\n남은 것은 **자료 쪽** — `mach_fuel_rate` 가 휘발유 1.3ℓ 를 담고 있고, 그것은 원문에 없는 값을 **옛 벌에서 이어받은 것**(`_build_mach.py` 의 이어받기 · 다시 뽑을 때마다 `이어받음 {'fuel': 1}` 로 보고됨). 닫는 길은 둘 — ㉠ 원문에 없으니 **비움**(랩탑 메인이 이 줄만 이어받지 않게) · ㉡ 전력 기종의 기름 값을 사람이 정해 넣는 자리로 **남김**(그러면 「사람이 넣은 값」 표시를 달 것). 어느 쪽인지는 판정 자리라 그대로 둠 — 지어 채우지 않음.\n⭐ **잠정 처리(2026-09-18 브레인 B28) — 남김.** 「지우는 것보다 남기는 것이 안전 · 애매하면 남기고 사유」가 이 판의 확정 잣대라(계수 절단 사고 뒤 세운 것) 휘발유 1.3ℓ 를 **지우지 않고 표시만 단다.** 비울지 사람값 자리로 굳힐지는 **사용자 판단 목록 일곱째**로 올라가 있음 — 회신 오면 확정. ⚠ 다시 뽑을 때 보고에 뜨는 `이어받음 {'fuel': 1}` 은 **표시가 일이니 끄지 말 것.**", - "표시": "원문 부재 · 옛 벌 이어받음 · 사람 확인 필요", - "잠정": "남김 — 사용자 판단 목록 일곱째" - } - }, + "machine": {}, "material": {}, "oil": {}, "rate": {}, @@ -180,7 +142,6 @@ "갈래별": { "낳은 값": 1, "메모": 1, - "살림살이": 1, "요약 이름": 2, "원문 부재": 25, "자리 표시": 2, @@ -188,7 +149,7 @@ }, "셈": { "labor_blind": 5, - "machine_blind": 9, + "machine_blind": 8, "material_blind": 2, "oil_blind": 7, "rate_blind": 11 @@ -215,15 +176,6 @@ "class_why": "자료가 낳은 값 — 「계」 계수(10-7)를 10,000,000 으로 나눈 것이다. 낳은 밑값인 계수 넷은 이미 줄마다 맞대고 있어 여기서 또 맞대면 같은 것을 두 번 세는 셈이다.", "갈래": "낳은 값" }, - "안 잰 칸 mach_fuel_rate.parse_method": { - "what": "원문과 안 맞댐", - "why": "추출기 살림살이 — 그 줄을 어떻게 읽었나 적어 둔 표시(`verified_source_row_alignment`)다. 원문에 없는 말이다.", - "class": "㉮ 영영 할 일 아님", - "owner": "랩탑 메인", - "owner_ask": "기계 원천 벌(mach_base_2026.json) 재추출 — 그 추출기가 이 저장소에 없어 우리가 못 돌림", - "class_why": "추출기 살림살이 — 그 줄을 어떻게 읽었나 적어 둔 표시(`verified_source_row_alignment`)다. 원문에 없는 말이다.", - "갈래": "살림살이" - }, "안 잰 칸 mach_fuel_rate.source_tables.section": { "what": "원문과 안 맞댐", "why": "표를 가리키는 이름표일 뿐 — 8-4 표의 머리와 줄은 이미 **표째 통째로** 맞대고 있다(`운전경비 원표 N번째`).", @@ -494,10 +446,18 @@ "_갈래": { "센 날": "2026-09-18", "셈": { - "원문 부재 / ㉰": 10, + "원문 부재 / ㉰": 7, "잣대 못 알아봄 / ㉯": 7 }, "잣대": "두 갈래로 가름 — **원문 부재**: 값이 원문·원천에 없거나 원문 밖 말이라 채울 것이 없음 · **잣대 못 알아봄**: 값은 원문에 있는데 전사·읽기가 못 가름 ⇒ 고치면 풀림. ㉮ 영영 할 일 아님 · ㉯ 남이 고쳐야 풀림 · ㉰ 사용자·브레인 판단.", - "할 일 아님으로 뺀 줄": 34 + "할 일 아님으로 뺀 줄": 33, + "닫힌 자리": [ + { + "날": "2026-09-18", + "무엇": "양수기 7993-0020 휘발유 1.3ℓ (어긋남 세 줄)", + "어떻게": "원문 규명으로 닫힘(브레인 B30) — PDF 340쪽 주연료표의 「휘발유1.3」은 **바로 윗줄 7992(모르타르 믹서)** 것이고 양수기 줄은 전력 1.49㎾ 뿐이었음. 옛 추출이 **이웃 줄 값을 물려받은 자리 틀림**. ⇒ 「원문 부재」가 아니라 **이웃 줄 오귀속**이었음.", + "처리": "`mach_base_2026.json` 의 양수기 연료 줄을 지우고 다시 뽑음. 이어받기는 **옛 벌을 보고 되살리므로** 한 번 지워야 영영 안 돌아옴(`이어받음 {'fuel': 1}` → **0**). 7992 쪽 휘발유 1.3 은 이미 갈라 들어가 있음." + } + ] } }