chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합

- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ahnyongjooandClaude Sonnet 5.5 committed 2026-10-28 11:20:18 +09:00
commit 964a841de1
3978 files changed
+58013356

No files matched your search

@@ -0,0 +1,81 @@
"""Stage A (2026-10-16): web/app.py pier page metadata, F-field edit rule (D3) and V3 edit block; web/store.py edit log.
Backup in backup/2026-10-16_묶음개편A전/. Refuses to run twice."""
from pathlib import Path
APP = Path(__file__).resolve().parents[2]
A, S = APP / "web" / "app.py", APP / "web" / "store.py"
def patch(path, pairs):
s = path.read_text(encoding="utf-8")
assert "# stage A 2026-10-16" not in s, f"{path.name} already patched"
for a, b in pairs:
assert s.count(a) == 1, (path.name, a[:60])
s = s.replace(a, b)
path.write_text(s, encoding="utf-8")
patch(S, [(
' def set_section(self, which, key, value):',
''' def log_fixed_edit(self, which, key, paths, reason):
"""Record of an edit of fixed (F) fields with its reason (D3) # stage A 2026-10-16"""
log = rjson(self.dir / "edit_log.json", [])
log.append({"at": now(), "section": f"{which}:{key}", "fixed_fields": paths, "reason": reason})
wjson(self.dir / "edit_log.json", log)
def set_section(self, which, key, value):''')])
patch(A, [
("from engine import recommend, reader, report_files # noqa: E402", "from engine import recommend, reader, report_files, variability # noqa: E402"),
(''' secs = []
for s in p.sections():
secs.append(dict(s, **p.section_state(s["file"], s["key"])))
''', ''' secs = []
req = required(p)
for s in p.sections():
secs.append(dict(s, **p.section_state(s["file"], s["key"]), meta=p.section_meta(s["file"], s["key"]),
required=(s["file"], s["key"]) in req))
origin_same = [s for s in secs if s["required"] and s["meta"]["origin"]] # stage A 2026-10-16
'''),
(''' return render_template("pier.html", p=p, sections=secs, gates=gates, need=unconfirmed(p),''',
''' return render_template("pier.html", p=p, sections=secs, gates=gates, need=unconfirmed(p), origin_same=origin_same,
has_origin=bool(p.info.get("origin")), grades=variability.GRADES,'''),
(''' text = json.dumps(d[key], ensure_ascii=False, indent=1)
if request.method == "POST":
text = request.form["value"]
try:
p.set_section(which, key, json.loads(text))
flash("저장했습니다. 확정하려면 '확정'을 누르세요.", "ok")
return redirect(url_for("section", name=name, which=which, key=key))
except (ValueError, json.JSONDecodeError) as e:
flash(f"저장 안 됨: {e}", "fail")
return render_template("section.html", p=p, which=which, key=key, text=text, st=p.section_state(which, key))''',
''' text = json.dumps(d[key], ensure_ascii=False, indent=1)
meta = p.section_meta(which, key)
if request.method == "POST":
text = request.form["value"]
reason = request.form.get("reason", "").strip()
try:
new = store.expand_chains(json.loads(text))
if meta["grade"] == "V3":
raise ValueError("생성 변수(V3)는 화면에서 직접 고칠 수 없습니다. 판독 스크립트를 다시 실행해 목록을 만든 뒤 반영하세요")
fixed = ["(묶음 전체)"] if meta["grade"] == "F" and new != d[key] else variability.changed_fixed(d[key], new, meta["fixed_fields"])
if fixed and not reason:
raise ValueError(f"고정(F) 항목({', '.join(fixed)})을 바꾸면 같은 템플릿이 아닐 수 있습니다. 바꾸는 사유를 입력하세요")
p.set_section(which, key, new)
if fixed:
p.log_fixed_edit(which, key, fixed, reason)
flash("저장했습니다. 확정하려면 '확정'을 누르세요." + (" 고정 항목 변경 사유를 기록했습니다." if fixed else ""), "ok")
return redirect(url_for("section", name=name, which=which, key=key))
except (ValueError, json.JSONDecodeError) as e:
flash(f"저장 안 됨: {e}", "fail")
return render_template("section.html", p=p, which=which, key=key, text=text, st=p.section_state(which, key), meta=meta,
grades=variability.GRADES)'''),
('''def unconfirmed(p):''', '''def required(p):
"""Bundles any gate of the pier's scope needs (existing ones)."""
return {(r["file"], r["key"]) for g in p.scope() for r in p.gate_requirements(g) if r["exists"]}
def unconfirmed(p):'''),
])
print("patched app.py, store.py")