본문으로 건너뛰기

ADR 0059: docgen 주 동선 학습 단절 해소 — 편집기 유도 동선

2026-06-29 golden QA tenant 실측 디버깅(세션 메모리 project_golden_qa_tenant_strategy_2026_06_28) 중 wren·lex·remy·piper 4에이전트 분석으로 발견된 known gap 의 결정. 최종 결정은 CTO 김현우.

상태 = Accepted (2026-06-29): Open questions 3건이 lex 도메인 검증 → CTO 결정으로 해소 — ① staff finalize 동등 적격(변호사법 §22 감독 하 적법·§109 무관, finalizedByRole 메타로 추적) ② 실명·주소 redact 갭은 PR #3126(party-name-redactions 결정론 치환 + 주소 정규식)으로 차단 ③ CTA 비강제(다운로드만 OK). MVP 1차(Step3 CTA + openTextInEditorAction 재사용)는 PR #3127 머지, 후속(확정 다이얼로그 안심3줄·finalizedByRole·주석 정정)은 본 후속 PR.

배경 — 주 동선이 학습되지 않는다 (known gap, 의도된 분리 아님)

너홀로프로의 한 줄 본질 = "법률 사무소가 자기 데이터로 자기 AI 를 학습·활용해, 소송을 더 빠르고 정확하게 관리." 이 본질의 핵심 구현체가 사무소 서면을 차기 사건 서류 생성에 자동 참조하는 two-RAG 결합(ADR 0041)이며, 그 학습 재료(authored)는 변호사가 확정(finalize) 한 서면에서 나온다.

그런데 변호사의 주 동선("서류 작성" → /docs/catalog/docs/generate)으로 만든 서류는 학습에 들어가지 않는다. 코드로 확정한 두 경로의 분기:

경로 A — docgen 주 동선 (학습 안 됨)

  • 진입: DocCenterClient.tsx "서류 작성" 버튼 → /docs/catalog/docs/generate (3-step 위저드).
  • 결과 화면 DocStep3Preview.tsx: 다운로드(downloadDocAsHwpx/downloadDocAsDocx, doc-download 유틸) + 저장(onSaveuseDocGenerate.ts handleSave).
  • 저장 실체: handleSavesaveDocWithHtmlAction(docs/_actions/doc-generate-actions.ts) → docsRef(tenantId).add(...).
  • docsRef 정의(apps/web/lib/firebase/paths.ts:155): tenantRef(tenantId).collection("documents") = tenants/{tid}/documents flat 서류센터. paths.ts:162 주석이 못 박음: "서류 센터(tenants/documents)는 caseId 무관."
  • finalize 없음·_learningFeedText 없음·cases/{caseId}/documents 경로 아님 → 학습 트리거가 물리적으로 발화 불가.

경로 B — 편집기 확정 동선 (학습 됨, 부 동선)

  • finalizeDocumentAction(cases/_actions/finalize-document-action.ts):
    1. redactText(plainText, "strict") fail-closed PII 비식별 (line 68, RedactionResidualError 잔여 검출 시 throw).
    2. caseRef(...).collection("documents") 의 문서에 finalizedAt + _learningFeedText(redacted) + _pendingLearningFeed = true 저장 (헤더 주석 line 11–12).
  • 트리거 onEditableDocumentFinalized(functions/src/on-document-finalized.ts:25): 바인딩 = tenants/{tenantId}/cases/{caseId}/documents/{docId}. _learningFeedText 를 읽어 sourceType: "document"(authored 를 document 로 매핑, on-document-finalized.ts:120) 로 tenant legacyDocuments 임베딩 → tenant RAG.

단절의 근거 (코드 + ADR)

  • 두 컬렉션 완전 별개: 경로 A 는 tenants/{tid}/documents(flat), 경로 B 는 tenants/{tid}/cases/{caseId}/documents. 트리거 바인딩이 후자라 서류센터에 절대 발화하지 않는다.
  • ADR 0018(학습 루프) 원안: 편집기(finalizeDocument)가 generateDocxAction대체하는 그림이었고, "현행유지(둘 병존)"는 명시적으로 거부됐다. 그러나 실제로는 docgen 이 주 동선으로 남아 두 경로가 병존 → 원안 미수렴.
  • ADR 0056(서류 우선 작성) 이 이 단절을 직접 규정: 대안 표 "완전 분리" 행 = "RAG 학습 trigger(on-document-finalized.ts)가 cases/CASEID/documents 경로라 사건 없으면 학습 신호가 물리적으로 불가 = 한 줄 본질 위배." P5 Minority Report = "기존 docgen 도 학습 루프에 제대로 들어가는지 선결 점검." 후속 과제 #5 로 못 박음 → 본 ADR 이 그 #5 의 검증 결과(미진입 확정)에 대한 해소책.
  • golden tenant 실측(2026-06-28): "authored finalize/trigger 갭 발견 — 서류 저장 ≠ authored 생성." 코드 grep 으로 동일 결론.

주석 드리프트 (정정 대상)

  • DocCenterClient.tsx:165 주석: "서류 작성 = 카탈로그(소송 단계별 유형 선택)에서 시작 → 편집기 (ADR 0056)." — 실제로 /docs/catalog/docs/generatedocgen flat 저장(경로 A) 이지 편집기(경로 B)가 아니다. "→ 편집기" 는 사실과 다른 오인 표현. 본 ADR 의 동선이 구현되기 전까지는 "→ 서류센터 flat 저장(학습 미진입)" 이 정확하며, 구현 후에는 "→ (선택 시) 편집기 → 확정 → 학습" 으로 갱신해야 한다. devon 구현 PR 에서 이 주석을 현행 정확성에 맞게 정정한다(아래 결과 §주석 정정 참조).

결정 — 편집기 유도 MVP (비강제 제3선택지)

docgen 결과 화면에 편집기로 다듬어 확정하는 동선을 다운로드/flat저장과 동렬의 제3선택지(비강제) 로 추가한다. docgen 산출물을 학습에 직접 편입하지 않는다(아래 거부된 대안 (a) 참조). 변호사가 자기 의지로 "확정"을 거쳐야만 학습에 들어가는 ADR 0018·#3113 의 authored 철학을 보존한다.

1. docgen Step3 CTA — 동렬 비강제

DocStep3Preview"편집기에서 다듬어 확정" CTA 를 다운로드 버튼들과 동렬로 추가. "건너뛰고 다운로드만 해도 됩니다" 를 명시해 빠른 다운로드 동선은 0 변경(ADR 0056 의 "가벼움" 유지). noCaseMode(사건 없이 작성/연습)면 CTA 미렌더 — finalize 가 caseId 필수이므로(DocStep3Preview.tsx:25 의 noCaseMode 주석과 정합).

2. openTextInEditorAction 재사용 — 신규 액션·컬렉션 0

편집기 진입은 기존 openTextInEditorAction(cases/_actions/open-text-in-editor-action.ts) 을 재사용한다. 현재 유일 호출부는 JudgmentSection.tsx(판결문 → 편집기). Input caseId: string 필수(line 29) + validateCaseId 게이트(line 42) → 내부적으로 createEditableDocument(cases 경로) 생성 → 편집기. 신규 Server Action·신규 컬렉션·신규 스키마 0.

  • caseId 가 없는 경우(docgen 을 사건 없이 시작): ADR 0056 승격 모달(① 새 사건 등록 / ② 기존 사건 연결 / ③ 상담 보관)을 먼저 띄워 caseId 를 확보한 뒤 편집기로 진입. 승격(ADR 0056)과 학습(본 ADR)이 한 동선으로 합쳐진다.

3. 확정 → authored (경로 B 재사용)

편집기에서 다듬은 뒤 "검토 완료 → 확정하고 학습" 다이얼로그 → finalizeDocumentAction(strict redact fail-closed) → cases/{caseId}/documents finalize → onEditableDocumentFinalized 트리거 → authored 임베딩. 경로 B 를 그대로 탄다 — 학습 신호 검증된 경로 재사용.

  • 확정 다이얼로그에 안심 3줄 보강: 🔒 자동 비식별(strict redact) · ⛉ 사무소 전용(tenant 격리, cross-tenant 유통 없음) · ↺ 언제든 해제. PII·격리 불안을 선제 해소(remy).

4. 진술서류 우선, 형사·신청 Phase 2

소장·답변서·준비서면(진술서류) 우선 적용. 신청서류·형사 docType 은 redact 충분성(Open question 2) 확정 후 Phase 2. owner·staff 모두 대상(단 staff 동등성 = Open question 1).

5. 북극성 지표 = docgen → authored 전환율

성공 지표는 "docgen 진입 → finalize(authored) 전환율"(진입율 × finalize율). "docgen 생성 건수" 를 보지 않는다 — 측정하는 것이 만들어지므로(ADR 0056 §6 와 동일 철학), 생성 건수를 최적화하면 학습 안 되는 .docx 양산에 최적화된다. leave-one-out 회귀는 golden tenant eval --tenant(PR #3124)로 production smoke 에서 측정(Platform RAG 가 에뮬레이터 부재라 라이브 임베딩 검증은 production 영역).

거부된 대안

대안거부 이유
(a) docgen 직접 학습 편입saveDocWithHtmlAction 저장 시 자동으로 학습 feed(1) PII raw 통과: docgen 어댑터는 주민번호를 raw 로 통과시킨다 — docgen-adapter.test.ts:175fields["plaintiff.residentId"]).toBe("110111-1234567") 로 고정. authored 의 redactText(strict) fail-closed 게이트를 우회 → 비밀유지의무(변호사법 §26) 사고 위험. (2) 미완성 골격: docgen 산출물은 논증이 비어 있고 [변호사 성명] 등 placeholder 가 남은 초안 — 학습 재료로서 품질 오염. (3) #3113 위배: authored 화이트리스트(검색 시점 sourceType 게이트, project_legacy_learning_material_gate_2026_06_27)는 "변호사가 확정한 서면" 만 적격으로 본다. 자동 편입은 이 철학을 깬다.
(c) 현행 유지 — docgen 은 학습 안 되는 채로 두고 편집기 동선만 별도 안내한 줄 본질 위배: 주 동선이 비학습이면 사무소 자산이 차기 사건에 환류되지 않아 "자기 데이터로 자기 AI 학습"이 실질 동작하지 않는다. ADR 0056 P5 Minority 가 선결 점검을 요구한 것도 이 때문. 현행 유지 = 후속 과제 #5 의 "검증 후 무대응".
(d) docgen 저장 경로를 cases/{caseId}/documents 로 변경 (서류센터 폐기, finalize 강제)(1) 빠른 다운로드·flat 서류센터의 가벼움(ADR 0056)을 파괴. (2) 모든 docgen 산출물에 strict redact 강제 = (a)의 PII 게이트는 해결하나 "초안만 빠르게" 니즈를 막아 진입 마찰 급증. (3) 비강제 원칙 위배. 본 ADR 은 두 컬렉션을 유지하고 선택적 다리만 놓는다.

Open questions (lex 검증 → CTO 결정 대기, 미결)

아래 3건은 미결이다. CIO/CEO 사람 검수 단계를 임의로 끼우지 않고(feedback_legal_domain_lex_verifies_cto_decides), lex 도메인 검증 → 선택지 → CTO 결정 순서로 닫는다. 구현(devon) 착수 전 결정 필요.

  1. staff finalize 학습 동등성 — 사무장(staff)이 확정한 서면도 변호사(owner) 서면과 동등하게 authored 적격인가? golden tenant omission 갭과 직결되며, 변호사법상 서면 작성 주체의 책임 범위와 맞물린다. (현 코드는 finalize 권한을 owner/staff 로 구분하지 않으나, 학습 적격성은 별개 판단.)
  2. 진술서류 redact 충분성 — 소장·답변서는 실명·주민번호·주소가 밀집한다. strict redact 가 진술서류 전량의 PII 무누출을 보장하는가? 형사 docgen(11종) 확대 시 추가 마스킹 규칙이 필요한가? (Phase 2 게이트와 직결.)
  3. 승격 강제 vs 비강제 — MVP 는 비강제(다운로드만 OK)라 학습 전환율이 승격률에 종속된다. 일부 docType(예: 진술서류)은 더 강한 넛지가 정당한가, 아니면 가벼움 우선으로 전 docType 동렬 비강제 유지인가?

교차 링크

성공 판정

  • docgen Step3 에서 "편집기에서 다듬어 확정" CTA 가 다운로드/저장과 동렬로 노출(비강제, "건너뛰고 다운로드만" 명시).
  • CTA → (caseId 있으면) openTextInEditorAction 편집기 진입 / (없으면) ADR 0056 승격 모달 → 편집기. 신규 액션·컬렉션 0.
  • 편집기 확정 → cases/{caseId}/documents finalize → onEditableDocumentFinalized 트리거 → authored 임베딩(경로 B 재사용).
  • 빠른 다운로드 동선 회귀 0(좌표 assertion).
  • DocCenterClient.tsx:165 주석이 현행 정확성으로 정정됨.
  • docgen → authored 전환율 텔레메트리 계측 가능. golden tenant eval --tenant leave-one-out 통과(production smoke).
  • Open questions 3건이 CTO 결정으로 닫힌 뒤 status 를 Accepted 로 승격.