feat(M02): 338-3b 확인한 줄만 사전조합 — Build 새 몸 · 재검사 · 별칭 장부 씀 · 장부 길 · 옛 즉시 확정 길 없앰

- M02_Hopyo_Build — 몸 줄만(없으면 400) · 대상 여럿 같은 별칭 · 배 · 몫 · 통째 · 하위 호표 확인 전 409 · 본뜬 원본 · 확인 · 같은 본뜬 덮음 · confirmed(folder, source)
- M02_Labor_Router — hopyo-build 엄격 몸(extra forbid) · hopyo-ledger GET · PUT · hopyo-memory 없앰 · picks 확인 · 올린 뒤 Fit.ensure · 시동 Ours.warm(있을 때만) · ?to= 만들 층
- M02_Hopyo_Ledger — times_of 나눔
- 시험 test_m02_hopyo_build.py 새로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
This commit is contained in:
2026-10-15 23:21:09 +09:00
co-authored by Claude Opus 5.5
parent ea21006352
commit bf5d130e32
4 changed files with 508 additions and 223 deletions
+14 -8
View File
@@ -178,9 +178,21 @@ def check_pair(raw: Any, where: str, known: tuple[set[str], set[str]]) -> dict[s
values = raw.get("입력값") or {}
if not isinstance(values, dict) or (mat and values):
raise _bad(f"입력값이 틀림 「{where}」")
unknown = set(values) - input_names(code) if code else set()
unknown = set(values) - input_names(code) if code and values else set()
if unknown:
raise _bad(f"모르는 입력 {sorted(unknown)} 「{where}」")
times, part = times_of(raw, where)
head = {"로직": code} if code else {"자재": mat}
return {
**head,
"입력값": values,
"배": times,
"몫": part,
}
def times_of(raw: dict[str, Any], where: str) -> tuple[int | float, int | float | None]:
"""(배, 몫) 재검사 — 배 0 넘는 수 · 몫 없음 또는 (0, 1]."""
times = _number(raw.get("배", 1))
if times is None or times <= 0:
raise _bad(f"배는 0 넘는 수 「{where}」")
@@ -188,13 +200,7 @@ def check_pair(raw: Any, where: str, known: tuple[set[str], set[str]]) -> dict[s
part = None if share is None else _number(share)
if share is not None and (part is None or not 0 < part <= 1):
raise _bad(f"몫은 0 넘고 1 이하 「{where}」")
head = {"로직": code} if code else {"자재": mat}
return {
**head,
"입력값": values,
"배": _json(times),
"몫": None if part is None else _json(part),
}
return _json(times), None if part is None else _json(part)
def check(full: str, raw: Any, known: tuple[set[str], set[str]] | None = None) -> dict[str, Any]: