fix(B08): 품셈 밑수를 원문 본문에서 읽음 — 곱셈 10배·100배 오차 자리

서브 창 제보(기준 단위 없이 도는 단가 125 중 122)의 뿌리. 밑수는 표 안이 아니라
**표 바로 위 본문**에 있음 — `### 12-2. 표면 마무리` 다음 줄의 `(단위: ㎡당)`.
표만 보면 못 찾고, 못 찾은 채 두면 「10㎡당」 표를 1㎡당으로 알아 곱셈이 10배 틀림.

- 원문 md 를 함께 열어 표 위 6줄에서 밑수를 읽음. **본문이 정본, 표 안 긁기는 보조** —
  13-3-1 이 본문 `(단위: ㎥당)` 인데 표 안 긁기가 비고의 `10㎡` 를 물어 오던 자리.
- `(단위: 인/㎡당)` 꼴은 **분모가 밑수** — 값의 단위(인)를 밑수로 읽으면 뜻이 뒤집힘.
- ⚠ 「당」도 「단위:」도 없으면 밑수가 아님. 처음에 조건을 느슨히 두어
  `(무한궤도,0.7㎥)` 를 「0.7㎥당」으로 읽어 5건이 잘못 잡혔음 — 조여서 고침.
- 위로 거슬러 보되 **다른 표에 닿으면 멈춤** — 앞 표의 밑수를 물어 오면 조용히 틀림.

밑수 확보 13 → 183 (그중 묶음 기준 36건: 떼채취 100㎡ · 큰돌쌓기 10㎡ ·
뒷채움 100㎡ · 묘목 1000본 · 헬기방제 160ha 등). 못 찾은 144건은
`basis_missing_2026-01-01.json` 으로 냄 — 곱해야 하는 형태만 담아 잡음을 줄임.
빈칸으로 두면 1단위당으로 오해되므로 목록으로 드러냄.

앞서 확인한 「밑수가 밀렸나」와는 다른 물음이었음 — 이번은 「아예 안 적혔나」.

검증 — 품셈 30건 통과, 전체 575 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-08 01:02:21 +09:00
co-authored by Claude Opus 5
parent 7c14d33f97
commit c357381355
4 changed files with 1829 additions and 370 deletions
+147 -24
View File
@@ -237,6 +237,58 @@ def detect_form(table: dict[str, Any], chapter: str | None) -> tuple[str, str]:
BASIS_RE = re.compile(r"(\d[\d,.]*)\s*(㎥|m3|㎡|m2|㏊|ha|km|㎞|m|인|본|개|kg|㎏|톤|ton)\s*당")
# ⚠ **밑수는 표 안이 아니라 표 바로 위 본문에 있다** (2026-09-07 서브 창 제보로 파고 확인).
# `### 12-2. 표면 마무리` 다음 줄에 `(단위: ㎡당)` 이 오는 식이다. 표만 보면 못 찾고,
# 못 찾은 채로 두면 「10㎡당」 표를 1㎡당으로 알아 **곱셈이 10배 틀린다**.
# 앞서 확인한 「밑수가 **밀렸나**」와는 다른 물음이다 — 이번은 「**아예 안 적혔나**」다.
# ⚠ **「당」 또는 「단위:」 가 있어야 밑수다.** 둘 다 없으면 규격일 뿐이다 —
# 만들다 실제로 걸렸다: `(무한궤도,0.7㎥)` 를 「0.7㎥당」으로 읽어 5건이 잘못 잡혔다.
#: ⚠ `(단위: 인/㎡당)` 꼴 — **분모가 밑수**다. 값의 단위(인)를 밑수로 읽으면 뜻이 뒤집힌다.
SOURCE_BASIS_RATIO_RE = re.compile(
r"[(]\s*단위\s*[:]\s*[^)/]+/\s*([\d,]*\.?\d*)\s*"
r"(㎥|m3|㎡|m2|㏊|ha|㎞|km|m|매|본|개소|개|인|공|kg|㎏|톤|ton|주|식|대)\s*당\s*[)]"
)
SOURCE_BASIS_RE = re.compile(
r"[(]\s*(?:"
r"단위\s*[:]\s*([\d,]*\.?\d*)\s*(?P<u1>㎥|m3|㎡|m2|㏊|ha|㎞|km|m|매|본|개소|개|인|공|kg|㎏|톤|ton|주|식|대)\s*당?"
r"|([\d,]*\.?\d*)\s*(?P<u2>㎥|m3|㎡|m2|㏊|ha|㎞|km|m|매|본|개소|개|인|공|kg|㎏|톤|ton|주|식|대)\s*당"
r")\s*[)]"
)
#: 표 위로 몇 줄까지 거슬러 볼 것인가. 더 올라가면 **앞 표의 밑수**를 잘못 물어 온다.
SOURCE_LOOKBACK = 6
def basis_from_source(lines: list[str], line_no: int) -> tuple[float | None, str | None]:
"""표 바로 위 본문에서 밑수를 읽는다. 못 찾으면 `(None, None)` — 1 로 단정하지 않는다.
⚠ 위로 거슬러 보되 **다른 표를 만나면 멈춘다**. 앞 표의 밑수를 물어 오면 조용히 틀린다.
"""
start = max(0, line_no - 1 - SOURCE_LOOKBACK)
for index in range(line_no - 2, start - 1, -1):
if index < 0 or index >= len(lines):
continue
text = lines[index].strip()
if text.startswith("|"):
break # 앞 표에 닿았다 — 그 위는 남의 밑수다
if m := SOURCE_BASIS_RATIO_RE.search(text):
raw = (m.group(1) or "").replace(",", "")
try:
quantity = float(raw) if raw else 1.0
except ValueError:
quantity = 1.0
return quantity, m.group(2)
if m := SOURCE_BASIS_RE.search(text):
unit = m.group("u1") or m.group("u2")
raw = (m.group(1) if m.group("u1") else m.group(3)) or ""
raw = raw.replace(",", "")
try:
quantity = float(raw) if raw else 1.0
except ValueError:
quantity = 1.0
return quantity, unit
return None, None
def detect_basis(table: dict[str, Any]) -> tuple[float | None, str | None]:
"""「100㎥당」 같은 밑수. 없으면 `(None, None)` — 단위당 1 로 단정하지 않는다."""
@@ -290,14 +342,31 @@ def variant_axis(table: dict[str, Any]) -> list[str]:
return seen[:24]
def basis_quantity_is_grouped(quantity: float | None) -> bool:
"""「10㎡당」처럼 **묶음 기준**인가. 1 이 아니면 곱셈이 그만큼 갈린다."""
return quantity is not None and abs(quantity - 1.0) > 1e-9
def build() -> dict[str, Any]:
data = json.loads(SOURCE.read_text(encoding="utf-8"))
tables = data["variables"]["pum"]["tables"]
# 원문을 함께 연다 — 밑수가 표 밖(본문)에 있기 때문이다. 못 열면 밑수 없이 간다.
source_lines: list[str] = []
for entry in data.get("sources") or []:
candidate = ROOT / str(entry.get("path") or "")
if candidate.is_file():
source_lines = candidate.read_text(encoding="utf-8").splitlines()
break
toc_table = next(t for t in tables if t["table_id"] == "F0001")
nodes = parse_toc(toc_table["rows"])
by_number = {n["number"]: n for n in nodes}
attached = 0
# ⚠ 밑수를 못 찾은 표 목록. 「곱하면 안 되는 줄」을 받는 쪽이 가릴 수 있게 낸다 —
# 빈칸으로 두면 「1단위당」으로 오해되어 곱셈이 10배·100배 틀린다.
basis_missing: list[dict[str, Any]] = []
basis_found = 0
basis_grouped = 0
orphans: list[dict[str, Any]] = []
undetermined: list[dict[str, Any]] = []
@@ -308,7 +377,31 @@ def build() -> dict[str, Any]:
number = section_number(section)
chapter = number.split("-")[0] if number else None
form, why = detect_form(table, chapter)
basis_qty, basis_unit = detect_basis(table)
# ⚠ **본문이 정본이다.** 표 안을 긁는 쪽은 보조 — 비고에 적힌 다른 기준
# (「10㎡당」 같은 참고 문구)을 그 표의 밑수로 잘못 물어 온다.
# 실제로 13-3-1 이 본문 `(단위: ㎥당)` 인데 표 안 긁기가 `10㎡` 를 물어 왔다.
basis_qty = basis_unit = None
if source_lines:
basis_qty, basis_unit = basis_from_source(source_lines, int(table.get("line") or 0))
if basis_qty is None and basis_unit is None:
basis_qty, basis_unit = detect_basis(table)
basis_source = "표 안" if basis_unit else None
else:
basis_source = "본문"
if basis_unit:
basis_found += 1
if basis_quantity_is_grouped(basis_qty):
basis_grouped += 1
elif form in ("requirement", "productivity"):
# 참조·계수표는 곱할 값이 아니므로 목록에 넣지 않는다 — 잡음이 되면 안 본다.
basis_missing.append(
{
"pum_table_id": table["table_id"],
"section": norm(table.get("section")),
"pum_form": form,
"line": table.get("line"),
}
)
shares = resource_shares(table)
# ⚠ 「값이 일부만 선 표」를 정상으로 흘려보내지 않는다. **몫이 적혀 있으면 부분값**으로
# 본다 — 관측한 25건 모두 장비 몫이 시공능력 공식으로만 적혀 있어 값이 아니었고,
@@ -324,6 +417,8 @@ def build() -> dict[str, Any]:
"form_basis": why,
"basis_quantity": basis_qty,
"basis_unit": basis_unit,
# 밑수를 어디서 읽었나 — 본문(정본) / 표 안(보조). 없으면 None.
"basis_source": basis_source,
"resource_shares": shares,
"partial_ratio": partial,
# 공식 기호가 이 표에 직접 있는가 — 없으면 앞 표에서 물려받는 모양이다.
@@ -355,36 +450,44 @@ def build() -> dict[str, Any]:
"sha256": sha256_of(SOURCE),
"file": SOURCE.name,
}
return {
"schema_version": SCHEMA_VERSION,
"dataset_id": "work_item_master_forest",
"effective_date": data["effective_date"],
"generated_at": datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds"),
"dataset_version": src_meta,
"policy": {
"axis": "work_item_only",
"resource_axis_owner": "B09",
"no_invented_values": True,
"raw_row_preserved": True,
return (
{
"schema_version": SCHEMA_VERSION,
"dataset_id": "work_item_master_forest",
"effective_date": data["effective_date"],
"generated_at": datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds"),
"dataset_version": src_meta,
"policy": {
"axis": "work_item_only",
"resource_axis_owner": "B09",
"no_invented_values": True,
"raw_row_preserved": True,
},
"stats": {
"toc_nodes": len(nodes),
"tables_total": len(tables) - 1,
"tables_attached": attached,
"tables_orphan": len(orphans),
"form_undetermined": len(undetermined),
"basis_found": basis_found,
"basis_missing": len(basis_missing),
"basis_grouped": basis_grouped,
},
"orphan_tables": orphans,
"work_items": nodes,
},
"stats": {
"toc_nodes": len(nodes),
"tables_total": len(tables) - 1,
"tables_attached": attached,
"tables_orphan": len(orphans),
"form_undetermined": len(undetermined),
},
"orphan_tables": orphans,
"work_items": nodes,
}, undetermined
undetermined,
basis_missing,
)
def main() -> None:
master, undetermined = build()
master, undetermined, basis_missing = build()
OUT_DIR.mkdir(parents=True, exist_ok=True)
date = master["effective_date"]
master_path = OUT_DIR / f"work_item_master_{date}.json"
undet_path = OUT_DIR / f"form_undetermined_{date}.json"
basis_path = OUT_DIR / f"basis_missing_{date}.json"
master_path.write_text(json.dumps(master, ensure_ascii=False, indent=1), encoding="utf-8")
undet_path.write_text(
@@ -402,6 +505,24 @@ def main() -> None:
encoding="utf-8",
)
basis_path.write_text(
json.dumps(
{
"schema_version": SCHEMA_VERSION,
"dataset_id": "work_item_master_basis_missing",
"effective_date": date,
"note": (
"밑수(「10㎡당」 같은 기준 수량)를 못 찾은 표. **1 단위당으로 단정하지 말 것** — "
"곱셈이 10배·100배 틀린다. 값을 곱해야 하는 형태(requirement·productivity)만 담는다."
),
"items": basis_missing,
},
ensure_ascii=False,
indent=1,
),
encoding="utf-8",
)
manifest = {
"schema_version": SCHEMA_VERSION,
"dataset_id": "data_work_item_master_manifest",
@@ -414,7 +535,7 @@ def main() -> None:
"sha256": sha256_of(p),
"size_bytes": p.stat().st_size,
}
for p in (master_path, undet_path)
for p in (master_path, undet_path, basis_path)
],
}
(OUT_DIR / "_manifest.json").write_text(
@@ -427,6 +548,8 @@ def main() -> None:
f"표 귀속 {s['tables_attached']} / {s['tables_total']} (미귀속 {s['tables_orphan']})"
)
print(f"형태 미판정 {s['form_undetermined']}")
print(f"밑수 확보 {s['basis_found']} (묶음 기준 {s['basis_grouped']})")
print(f"밑수 미확보 {s['basis_missing']}{basis_path.name}")
print(f"산출 {master_path.relative_to(ROOT)}")
@@ -1,7 +1,7 @@
{
"schema_version": "1.0",
"dataset_id": "data_work_item_master_manifest",
"generated_at": "2026-09-08T00:36:35+09:00",
"generated_at": "2026-09-08T01:00:54+09:00",
"built_by": "B08_Quantity/B08_Quantity_Build_WorkItemMaster.py",
"source": {
"dataset_id": "pum_forest",
@@ -12,13 +12,18 @@
"files": [
{
"file": "work_item_master_2026-01-01.json",
"sha256": "fa9a1e9d84e1172568f074f8eb5ca2042eedefecb1146d9d4edf2044df9e26d9",
"size_bytes": 771414
"sha256": "fe454c56c9dc01ad7dae04a8f90d776d08c5ce33badeadb2606b35234bfce7eb",
"size_bytes": 785034
},
{
"file": "form_undetermined_2026-01-01.json",
"sha256": "7334dab9385bc1615a9cdb557ba814482e9a63d83b9e1232946918bfd8b5577f",
"size_bytes": 37139
},
{
"file": "basis_missing_2026-01-01.json",
"sha256": "27f8d80d10b791df8502e633c1d279ce2acce63f871eae6b0c4eb26ca8290e2e",
"size_bytes": 20674
}
]
}
@@ -0,0 +1,872 @@
{
"schema_version": "1.0",
"dataset_id": "work_item_master_basis_missing",
"effective_date": "2026-01-01",
"note": "밑수(「10㎡당」 같은 기준 수량)를 못 찾은 표. **1 단위당으로 단정하지 말 것** — 곱셈이 10배·100배 틀린다. 값을 곱해야 하는 형태(requirement·productivity)만 담는다.",
"items": [
{
"pum_table_id": "F0042",
"section": "2-1-1. 휘발유․오일",
"pum_form": "requirement",
"line": 1305
},
{
"pum_table_id": "F0043",
"section": "2-1-1. 휘발유․오일",
"pum_form": "requirement",
"line": 1328
},
{
"pum_table_id": "F0049",
"section": "2-1-4. 페인트 및 마킹테이프",
"pum_form": "requirement",
"line": 1402
},
{
"pum_table_id": "F0050",
"section": "2-1-4. 페인트 및 마킹테이프",
"pum_form": "requirement",
"line": 1417
},
{
"pum_table_id": "F0052",
"section": "2-1-4. 페인트 및 마킹테이프",
"pum_form": "requirement",
"line": 1444
},
{
"pum_table_id": "F0061",
"section": "2-1-11. 지상 약제살포",
"pum_form": "requirement",
"line": 1570
},
{
"pum_table_id": "F0075",
"section": "3-1. 경계표시",
"pum_form": "requirement",
"line": 1731
},
{
"pum_table_id": "F0077",
"section": "3-3. 작업로 설치",
"pum_form": "requirement",
"line": 1754
},
{
"pum_table_id": "F0078",
"section": "3-4-3. 임산물 운반로 및 작업로 보수비 산정",
"pum_form": "requirement",
"line": 1815
},
{
"pum_table_id": "F0080",
"section": "3-6. 산물 임내정리",
"pum_form": "requirement",
"line": 1867
},
{
"pum_table_id": "F0081",
"section": "3-7. 재해산물 수집",
"pum_form": "requirement",
"line": 1887
},
{
"pum_table_id": "F0082",
"section": "3-8. 드론 영상 촬영",
"pum_form": "requirement",
"line": 1901
},
{
"pum_table_id": "F0083",
"section": "4-1-1. 임업용 동력기계톱",
"pum_form": "productivity",
"line": 1929
},
{
"pum_table_id": "F0084",
"section": "4-1-2. 하베스터(부착형 스트로크)",
"pum_form": "productivity",
"line": 1947
},
{
"pum_table_id": "F0085",
"section": "4-1-2. 하베스터(부착형 스트로크)",
"pum_form": "requirement",
"line": 1957
},
{
"pum_table_id": "F0086",
"section": "4-2-1. 100본당",
"pum_form": "requirement",
"line": 1967
},
{
"pum_table_id": "F0087",
"section": "4-2-2. 1,000㎡당",
"pum_form": "requirement",
"line": 1997
},
{
"pum_table_id": "F0088",
"section": "4-3. 위험목 베기",
"pum_form": "requirement",
"line": 2012
},
{
"pum_table_id": "F0089",
"section": "4-4. 가지정리",
"pum_form": "requirement",
"line": 2041
},
{
"pum_table_id": "F0090",
"section": "4-5. 벌도 위험목 점검",
"pum_form": "requirement",
"line": 2052
},
{
"pum_table_id": "F0091",
"section": "4-6. 벌목부 작업안전 보조",
"pum_form": "requirement",
"line": 2062
},
{
"pum_table_id": "F0092",
"section": "5-1-1. 관목굴취",
"pum_form": "requirement",
"line": 2081
},
{
"pum_table_id": "F0093",
"section": "5-1-2. 교목굴취(나무높이)",
"pum_form": "requirement",
"line": 2099
},
{
"pum_table_id": "F0094",
"section": "5-1-3. 교목굴취(근원직경)",
"pum_form": "requirement",
"line": 2125
},
{
"pum_table_id": "F0095",
"section": "5-1-3. 교목굴취(근원직경)",
"pum_form": "requirement",
"line": 2156
},
{
"pum_table_id": "F0097",
"section": "5-1-5. 떼운반 적재 기준표",
"pum_form": "requirement",
"line": 2177
},
{
"pum_table_id": "F0098",
"section": "5-2. 뿌리돌림",
"pum_form": "requirement",
"line": 2194
},
{
"pum_table_id": "F0099",
"section": "5-3-1. 나무식재",
"pum_form": "requirement",
"line": 2219
},
{
"pum_table_id": "F0102",
"section": "5-3-2. 관목식재(단식)",
"pum_form": "requirement",
"line": 2254
},
{
"pum_table_id": "F0103",
"section": "5-3-3. 관목식재(군식)",
"pum_form": "requirement",
"line": 2272
},
{
"pum_table_id": "F0104",
"section": "5-3-4. 교목식재(나무높이)",
"pum_form": "requirement",
"line": 2291
},
{
"pum_table_id": "F0106",
"section": "5-3-5. 교목식재(흉고직경)",
"pum_form": "requirement",
"line": 2322
},
{
"pum_table_id": "F0108",
"section": "5-3-5. 교목식재(흉고직경)",
"pum_form": "requirement",
"line": 2355
},
{
"pum_table_id": "F0109",
"section": "5-4. 파종조림",
"pum_form": "requirement",
"line": 2366
},
{
"pum_table_id": "F0110",
"section": "5-5. 천연하종갱신",
"pum_form": "requirement",
"line": 2383
},
{
"pum_table_id": "F0111",
"section": "5-6. 움싹갱신",
"pum_form": "requirement",
"line": 2396
},
{
"pum_table_id": "F0112",
"section": "5-7. 생태보완조림",
"pum_form": "requirement",
"line": 2409
},
{
"pum_table_id": "F0113",
"section": "5-8. 큰나무 공익조림",
"pum_form": "requirement",
"line": 2426
},
{
"pum_table_id": "F0114",
"section": "5-9. 해안조림",
"pum_form": "requirement",
"line": 2439
},
{
"pum_table_id": "F0116",
"section": "5-11. 사초심기",
"pum_form": "requirement",
"line": 2475
},
{
"pum_table_id": "F0117",
"section": "5-12. 떼붙임(재배잔디)",
"pum_form": "requirement",
"line": 2496
},
{
"pum_table_id": "F0118",
"section": "5-13. 떼심기",
"pum_form": "requirement",
"line": 2511
},
{
"pum_table_id": "F0121",
"section": "5-16-1. 단끊기",
"pum_form": "requirement",
"line": 2565
},
{
"pum_table_id": "F0126",
"section": "5-19-1. 표토절취 및 모으기",
"pum_form": "requirement",
"line": 2653
},
{
"pum_table_id": "F0129",
"section": "5-21. 표토이식",
"pum_form": "requirement",
"line": 2689
},
{
"pum_table_id": "F0132",
"section": "5-22-4. 평떼 시비",
"pum_form": "requirement",
"line": 2731
},
{
"pum_table_id": "F0143",
"section": "5-27. 식재면 관리",
"pum_form": "requirement",
"line": 2905
},
{
"pum_table_id": "F0144",
"section": "5-28-1. 짚망",
"pum_form": "requirement",
"line": 2919
},
{
"pum_table_id": "F0153",
"section": "6-1. 비료주기",
"pum_form": "requirement",
"line": 3062
},
{
"pum_table_id": "F0154",
"section": "6-2-1. 둘레베기",
"pum_form": "requirement",
"line": 3079
},
{
"pum_table_id": "F0155",
"section": "6-2-2. 줄베기",
"pum_form": "requirement",
"line": 3089
},
{
"pum_table_id": "F0156",
"section": "6-2-3. 모두베기",
"pum_form": "requirement",
"line": 3105
},
{
"pum_table_id": "F0157",
"section": "6-3. 맹아제거",
"pum_form": "requirement",
"line": 3122
},
{
"pum_table_id": "F0159",
"section": "6-4-2. 덩굴 약제 살포처리",
"pum_form": "requirement",
"line": 3153
},
{
"pum_table_id": "F0160",
"section": "6-4-3. 소금처리",
"pum_form": "requirement",
"line": 3164
},
{
"pum_table_id": "F0161",
"section": "6-4-4. 뿌리제거",
"pum_form": "requirement",
"line": 3183
},
{
"pum_table_id": "F0163",
"section": "6-5. 어린나무 가꾸기",
"pum_form": "requirement",
"line": 3244
},
{
"pum_table_id": "F0164",
"section": "6-6. 가지치기 및 수형교정",
"pum_form": "requirement",
"line": 3276
},
{
"pum_table_id": "F0165",
"section": "6-7-1. 교목 시비",
"pum_form": "requirement",
"line": 3304
},
{
"pum_table_id": "F0166",
"section": "6-7-2. 관목 시비",
"pum_form": "requirement",
"line": 3318
},
{
"pum_table_id": "F0170",
"section": "7-1-1. 수확",
"pum_form": "requirement",
"line": 3371
},
{
"pum_table_id": "F0171",
"section": "7-1-1. 수확",
"pum_form": "requirement",
"line": 3381
},
{
"pum_table_id": "F0172",
"section": "7-1-2. 숲가꾸기, 병해충방제",
"pum_form": "requirement",
"line": 3395
},
{
"pum_table_id": "F0174",
"section": "7-3. 아키야윈치(임업용 윈치) 집재",
"pum_form": "requirement",
"line": 3439
},
{
"pum_table_id": "F0175",
"section": "7-4-1. 수확",
"pum_form": "requirement",
"line": 3452
},
{
"pum_table_id": "F0176",
"section": "7-4-2. 숲가꾸기, 산림병해충방제",
"pum_form": "requirement",
"line": 3476
},
{
"pum_table_id": "F0177",
"section": "7-5-1. 수확",
"pum_form": "requirement",
"line": 3496
},
{
"pum_table_id": "F0178",
"section": "7-5-2. 숲가꾸기, 병해충방제",
"pum_form": "requirement",
"line": 3519
},
{
"pum_table_id": "F0179",
"section": "7-6. 스윙야더 집재",
"pum_form": "requirement",
"line": 3542
},
{
"pum_table_id": "F0180",
"section": "7-7-1. 수확",
"pum_form": "requirement",
"line": 3556
},
{
"pum_table_id": "F0181",
"section": "7-7-2. 숲가꾸기, 병해충방제",
"pum_form": "requirement",
"line": 3580
},
{
"pum_table_id": "F0182",
"section": "7-8-1. 가선설치",
"pum_form": "requirement",
"line": 3607
},
{
"pum_table_id": "F0183",
"section": "7-8-2. 가선해체",
"pum_form": "requirement",
"line": 3619
},
{
"pum_table_id": "F0184",
"section": "7-8-3. 집재 소요인력",
"pum_form": "requirement",
"line": 3631
},
{
"pum_table_id": "F0185",
"section": "7-9-1. 수확",
"pum_form": "requirement",
"line": 3656
},
{
"pum_table_id": "F0186",
"section": "7-9-2. 숲가꾸기, 소나무재선충병방제",
"pum_form": "requirement",
"line": 3673
},
{
"pum_table_id": "F0191",
"section": "7-11. 동력상하차기(우드그래플) 집재-수확",
"pum_form": "requirement",
"line": 3745
},
{
"pum_table_id": "F0192",
"section": "7-12. 동력상하차기(우드그래플) 집적",
"pum_form": "requirement",
"line": 3763
},
{
"pum_table_id": "F0201",
"section": "8-1-1. 약제주입기",
"pum_form": "requirement",
"line": 3945
},
{
"pum_table_id": "F0202",
"section": "8-1-2. 약제주입병",
"pum_form": "requirement",
"line": 3964
},
{
"pum_table_id": "F0203",
"section": "8-2-1. 소나무재선충병",
"pum_form": "requirement",
"line": 3982
},
{
"pum_table_id": "F0204",
"section": "8-2-1. 소나무재선충병",
"pum_form": "requirement",
"line": 3999
},
{
"pum_table_id": "F0206",
"section": "8-2-1. 소나무재선충병",
"pum_form": "requirement",
"line": 4023
},
{
"pum_table_id": "F0207",
"section": "8-2-1. 소나무재선충병",
"pum_form": "requirement",
"line": 4041
},
{
"pum_table_id": "F0209",
"section": "8-2-2. 솔잎혹파리",
"pum_form": "requirement",
"line": 4080
},
{
"pum_table_id": "F0210",
"section": "8-2-2. 솔잎혹파리",
"pum_form": "requirement",
"line": 4108
},
{
"pum_table_id": "F0211",
"section": "8-2-2. 솔잎혹파리",
"pum_form": "requirement",
"line": 4136
},
{
"pum_table_id": "F0213",
"section": "8-2-3. 솔껍질깍지벌레",
"pum_form": "requirement",
"line": 4182
},
{
"pum_table_id": "F0214",
"section": "8-2-3. 솔껍질깍지벌레",
"pum_form": "requirement",
"line": 4210
},
{
"pum_table_id": "F0215",
"section": "8-2-3. 솔껍질깍지벌레",
"pum_form": "requirement",
"line": 4238
},
{
"pum_table_id": "F0217",
"section": "8-2-4. 솔나방",
"pum_form": "requirement",
"line": 4279
},
{
"pum_table_id": "F0219",
"section": "8-2-5. 푸사리움가지마름병",
"pum_form": "requirement",
"line": 4320
},
{
"pum_table_id": "F0224",
"section": "8-5. 페르몬 유인트랩",
"pum_form": "requirement",
"line": 4434
},
{
"pum_table_id": "F0232",
"section": "8-7. 방제 실행 등록",
"pum_form": "requirement",
"line": 4583
},
{
"pum_table_id": "F0235",
"section": "8-9. 잔가지줍기",
"pum_form": "requirement",
"line": 4623
},
{
"pum_table_id": "F0236",
"section": "8-10. 그물망 피복",
"pum_form": "requirement",
"line": 4631
},
{
"pum_table_id": "F0237",
"section": "8-11. 이동식 임목 파쇄",
"pum_form": "productivity",
"line": 4649
},
{
"pum_table_id": "F0238",
"section": "9-2. 노선 굴진 보조원",
"pum_form": "requirement",
"line": 4675
},
{
"pum_table_id": "F0241",
"section": "9-4-1. 암파쇄",
"pum_form": "productivity",
"line": 4719
},
{
"pum_table_id": "F0244",
"section": "9-5-2. 깎기(90%)",
"pum_form": "productivity",
"line": 4759
},
{
"pum_table_id": "F0251",
"section": "9-8-1. T=30㎝ 미만",
"pum_form": "requirement",
"line": 4860
},
{
"pum_table_id": "F0294",
"section": "9-21. 제근",
"pum_form": "requirement",
"line": 5512
},
{
"pum_table_id": "F0310",
"section": "10-7-4. 모노레일 운반",
"pum_form": "requirement",
"line": 5770
},
{
"pum_table_id": "F0313",
"section": "10-8-1. 짐내리기",
"pum_form": "requirement",
"line": 5813
},
{
"pum_table_id": "F0314",
"section": "10-8-2. 운반대 설치",
"pum_form": "requirement",
"line": 5829
},
{
"pum_table_id": "F0317",
"section": "10-10-1. 콘크리트 및 골재운반(지상)",
"pum_form": "requirement",
"line": 5884
},
{
"pum_table_id": "F0318",
"section": "10-10-2. 그 외 자재의 운반품셈",
"pum_form": "requirement",
"line": 5894
},
{
"pum_table_id": "F0337",
"section": "12-5. 문양거푸집(07m)",
"pum_form": "requirement",
"line": 6217
},
{
"pum_table_id": "F0339",
"section": "12-7-1. 포장절단",
"pum_form": "requirement",
"line": 6254
},
{
"pum_table_id": "F0340",
"section": "12-7-2. 줄눈설치",
"pum_form": "requirement",
"line": 6269
},
{
"pum_table_id": "F0341",
"section": "12-8. 콘크리트 포장 거푸집",
"pum_form": "requirement",
"line": 6280
},
{
"pum_table_id": "F0350",
"section": "12-12. 날개벽",
"pum_form": "requirement",
"line": 6421
},
{
"pum_table_id": "F0379",
"section": "12-29. 스페이셔 설치(몰탈 블록)",
"pum_form": "requirement",
"line": 6775
},
{
"pum_table_id": "F0405",
"section": "13-3. 기초다짐 및 뒤채움’ 항을 적용한다.",
"pum_form": "requirement",
"line": 7087
},
{
"pum_table_id": "F0412",
"section": "13-4-4. 찰쌓기(인력)",
"pum_form": "requirement",
"line": 7174
},
{
"pum_table_id": "F0413",
"section": "13-4-4. 찰쌓기(인력)",
"pum_form": "requirement",
"line": 7185
},
{
"pum_table_id": "F0430",
"section": "13-10-2. 나무 말뚝박기",
"pum_form": "requirement",
"line": 7491
},
{
"pum_table_id": "F0437",
"section": "13-12-1. 뭉기기",
"pum_form": "requirement",
"line": 7612
},
{
"pum_table_id": "F0438",
"section": "13-12-2. 지오셀(사면보강)",
"pum_form": "requirement",
"line": 7625
},
{
"pum_table_id": "F0444",
"section": "13-14. 식생토낭 및 포트",
"pum_form": "requirement",
"line": 7715
},
{
"pum_table_id": "F0447",
"section": "13-15-2. 목책 설치",
"pum_form": "requirement",
"line": 7745
},
{
"pum_table_id": "F0454",
"section": "8-2-3 굴착기(2025)」를 참조하여 적용계수를 달리 적용하도록 한다.",
"pum_form": "requirement",
"line": 7983
},
{
"pum_table_id": "F0455",
"section": "2-1. 풀베기, (1) 둘레베기(조림목 본수 2,700본/ha, 조림1년차)",
"pum_form": "requirement",
"line": 8031
},
{
"pum_table_id": "F0456",
"section": "2-2. 풀베기, (2) 모두베기(조림목 본수 2,700본/ha, 조림2년차)",
"pum_form": "requirement",
"line": 8061
},
{
"pum_table_id": "F0457",
"section": "2-3. 풀베기, (3) 줄베기(조림목 본수 2,700본/ha, 조림2년차)",
"pum_form": "requirement",
"line": 8092
},
{
"pum_table_id": "F0458",
"section": "2-4. 풀베기, (4) 맹아제거+둘레베기(제거대상 맹아 1,000본/ha. 조림목 본수 2,700본/ha, 조림1년차)",
"pum_form": "requirement",
"line": 8124
},
{
"pum_table_id": "F0459",
"section": "2-5. 덩굴제거, (1) 지상부 덩굴걷기(큰나무 피해지. 덩굴 피복도 20~40%미만)",
"pum_form": "requirement",
"line": 8156
},
{
"pum_table_id": "F0460",
"section": "2-6. 덩굴제거, (2) 지상부 약제살포(큰나무 피해지. 덩굴 피복도 60~80%미만)",
"pum_form": "requirement",
"line": 8189
},
{
"pum_table_id": "F0461",
"section": "2-7. 덩굴제거, (3) 뿌리굴취(풀베기단계 조림지 1㎝미만 500본, 1~4㎝ 400본, 4㎝초과 100본)",
"pum_form": "requirement",
"line": 8225
},
{
"pum_table_id": "F0462",
"section": "2-8. 덩굴제거, (4) 뿌리굴취(풀베기단계 조림지 1㎝미만 500본, 14㎝ 400본,",
"pum_form": "requirement",
"line": 8265
},
{
"pum_table_id": "F0463",
"section": "2-9. 어린나무가꾸기, (1) 치수림단계 (20m 간격 소작업로 설치, 제거대상 피복도 ‘소’, 가지치기 미실행)",
"pum_form": "requirement",
"line": 8303
},
{
"pum_table_id": "F0464",
"section": "2-10. 어린나무가꾸기, (2) 유령림단계 (제거대상 피복도 ‘밀’, 가지치기 잣나무 02m. 500본/ha)",
"pum_form": "requirement",
"line": 8344
},
{
"pum_table_id": "F0465",
"section": "2-11. 솎아베기, (1) 산물을 임내에 버리는 경우",
"pum_form": "requirement",
"line": 8385
},
{
"pum_table_id": "F0466",
"section": "2-12. 솎아베기, (2) 산물을 전간재로 생산하는 경우",
"pum_form": "requirement",
"line": 8434
},
{
"pum_table_id": "F0467",
"section": "2-13. 위험목 베기",
"pum_form": "requirement",
"line": 8496
},
{
"pum_table_id": "F0468",
"section": "2-14. 산물수집, (1) 인력집재(단목 집재 + 집적)",
"pum_form": "requirement",
"line": 8542
},
{
"pum_table_id": "F0469",
"section": "2-15. 산물수집, (2) 지면끌기집재(공정별 독립작업)",
"pum_form": "requirement",
"line": 8585
},
{
"pum_table_id": "F0470",
"section": "2-16. 산물수집, (3) 지면끌기집재 (동시작업)",
"pum_form": "requirement",
"line": 8655
},
{
"pum_table_id": "F0471",
"section": "2-17. 산물임내정리",
"pum_form": "requirement",
"line": 8720
},
{
"pum_table_id": "F0472",
"section": "3-1. 임업용 동력기계톱, 우드그래플, 소형트럭",
"pum_form": "requirement",
"line": 8753
},
{
"pum_table_id": "F0473",
"section": "3-2. 임업용 동력기계톱, 스마트집재기, 우드그래플, 초소형포워더",
"pum_form": "requirement",
"line": 8828
},
{
"pum_table_id": "F0474",
"section": "3-3. 하베스터, 타워야더, 우드그래플, 소형포워더",
"pum_form": "requirement",
"line": 8912
},
{
"pum_table_id": "F0475",
"section": "4-1. 소나무재선충병방제",
"pum_form": "requirement",
"line": 8989
},
{
"pum_table_id": "F0476",
"section": "4-2. 참나무시들음병방제",
"pum_form": "requirement",
"line": 9106
}
]
}
File diff suppressed because it is too large Load Diff