diff --git a/docs/README.md b/docs/README.md
index 881abbf..9f11c5a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -81,6 +81,7 @@
| [`ops/nas-preview-g8-rollback-proof-runbook.md`](./ops/nas-preview-g8-rollback-proof-runbook.md) | G8 실제 receipt-bound image rollback 런북 — Gate6 helper 격리 계약 정정(소속 기준), 실행 순서, 금지 사항, 실패 복구 |
| [`ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json`](./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json) | G8 실제 rollback/restore 기계 판독 증거 — helper 격리, 두 executed receipt, HMAC journal 체인, DB lifecycle 집계, 정리 상태 |
| [`ops/evidence/google-account-data-recovery-2026-08-29.json`](./ops/evidence/google-account-data-recovery-2026-08-29.json) | Google identity alias 기반 관리자 데이터 복구의 백업·가드 트랜잭션·운영 DB·공개 런타임·Pages 승격 증거(실제 Gmail callback 미완료) |
+| [`ops/evidence/professor-summary-gap-deploy-2026-08-29.json`](./ops/evidence/professor-summary-gap-deploy-2026-08-29.json) | 교수자 검토 큐·요약 카드 12px 분리의 RED→GREEN·7폭/전체 시각 게이트·clean Pages 배포·실서비스 DOM 증거 |
| [`ops/public-db-recovery-rehearsal-2026-08-07.md`](./ops/public-db-recovery-rehearsal-2026-08-07.md) | 공개 DB 데이터 교체 사고의 RLS/volume 포렌식, 이중 dump, 격리 복구·최신 migration/API 리허설과 승인형 cutover/rollback 게이트 |
| [`ops/server-migration-runbook-draft.md`](./ops/server-migration-runbook-draft.md) | 서버 이관 런북 초안(자택→학교 정보처) — 이식성 이슈·DB dump/restore·엔진 모드 전환·검증 (초안) |
| [`ops/pilot-usage-guide-draft.md`](./ops/pilot-usage-guide-draft.md) | 파일럿 사용 지침 초안(대학원생 ~20명) — 접속·시간 기반 회기·라이브 코칭·유의사항 (초안) |
diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html
index 13a77ed..7a34176 100644
--- a/docs/dev_dashboard.html
+++ b/docs/dev_dashboard.html
@@ -698,6 +698,7 @@
216차 REQ-001 로그인 단순화(2026-08-29): 실제로 같은 startOAuth를 호출하던 학교용·다른 계정용 중복 버튼을 단일 Google 계정으로 로그인 CTA로 통합했다. 보조문구는 모든 Google 계정이며 Google authorize의 prompt=select_account는 남겨 공유 기기에서도 계정을 고를 수 있게 하고 특정 Workspace 도메인을 강제하는 hd는 보내지 않는다. Google이 검증한 이메일은 도메인·사전등록 제약 없이 즉시 승인되는 기존 서버 계약을 유지한다. 검증: auth API 41 passed, 직접 영향 desktop/mobile 32 passed, 인증 시각·경계폭 2 passed, 7폭 전체 레이아웃 15 passed, 세션 무회귀 8 passed, typecheck·lint·build 통과. 이 단일 CTA 번들은 아직 공개 미배포라 현재 공개 Pages의 기존 2버튼 DOM을 새 증거로 대체하지 않는다.
218차 Google 계정 데이터 복구·API 승격(2026-08-29): Gmail 로그인이 새 learner로 갈라져 정식 관리자 데이터가 사라져 보인 원인은 Google subject별 app_user가 둘로 생성된 것이었다. 이메일 자동병합 대신 owner-managed auth_identity_alias를 추가해 canonical 관리자에 Google subject 2개를 명시적으로 연결하고, 세션에는 실제 로그인 이메일을 별도 기록한다. 원본 백업 SHA c4725500…f2e9를 pg_restore --list로 확인한 뒤 복제 DB에서 복구 트랜잭션을 먼저 통과시켰다. Gmail 중복 계정의 상담 데이터는 0건이지만 설정 1행이 있어 첫 시도는 가드가 전부 rollback했고, 전체 FK 스캔 뒤 겹치는 설정값이 동일함을 확인해 source-only 알림 키만 canonical에 합치고 원본 설정 행은 보존했다. 활성 DB 결과는 canonical 21회기·64턴·평가 6건, 별칭 2·옛 Gmail 세션 0·감사로그 1·고아 0이며 사용자 1175·회기 469·평가 65를 유지한다. API+gateway 1111 passed/1 skipped, release agent 31 passed. detached-clean dba9b75a…·tree 14cd4607…에서 API/cloudflared fresh provenance를 발행하고 public health·DB·engine·voice·OpenAPI 129·auth 401을 확인했으며 boot/watchdog을 같은 핀으로 재등록해 LastTaskResult=0·failcount 0이다. 브라우저의 옛 Gmail 세션은 reload 후 /login으로 철회됐고, 실제 Gmail callback은 사용자 계정 선택 후 최종 확인한다.
219차 단일 Google 로그인 Pages 승격(2026-08-29): detached-clean dba9b75a…에서 typecheck·lint·cosmetic safety와 2회 byte-identical production build를 통과하고 최근 production 5개의 lazy asset 115개를 보존해 714파일을 Pages production ef48c0ae-374e-41fc-b6fd-03f69b26e946로 승격했다. custom domain은 새 entry index-B1rSWL_W.js SHA f8411694…b5bf, login chunk Login-DNNQ624T.js SHA f010f764…9c1d가 clean build와 일치하며, 단일 Google 계정으로 로그인 CTA 1개·구 계정 선택 버튼 0·dev login 0·console warning/error 0이다. 격리 Playwright의 공개 OAuth 시작 계약도 1 passed이고 이전 entry는 JavaScript MIME 200으로 보존된다. 배포별 preview origin은 같은 정적 자산을 받지만 서버 연결 진단을 표시하므로 runtime GREEN으로 기록하지 않는다. REQ-001은 실제 Gmail callback과 복구 계정의 관리자·21회기·64턴·평가 6건 확인 전까지 검토다.
+ 221차 교수자 콘솔 표면 간격 교정·공개 승격(2026-08-29): /teach의 검토 큐와 교수자 요약이 독립 Surface인데 부모 .pf-signal-strip의 gap:0 때문에 테두리·그림자가 맞붙던 원인을 --sp-3=12px로 교정했다. 수정 전 0px를 다시 주입해 새 회귀 검사가 RED가 되는 것을 확인하고 복원 뒤 focused 1 passed, 390~1440 7폭 교수자 gate 1 passed, 전체 layout visual 15 passed, session 무회귀 8 passed, typecheck·design SSOT·lint·build를 통과했다. tracked-clean 5bf89ff4…·tree 29f76aeb…에서 599파일 build 2회 byte-identical, 이전 자산 172개 보존 후 Pages production 0c60261e-cb37-482d-ba42-d91586194c48로 승격했다. 실서비스 1425×1272 DOM은 computed/실측 간격 12px·overflow 0·console warning/error 0이고 custom/preview의 Professor-BfR874KA.css SHA 63dbe2c7…7fff가 clean build와 일치한다. 증거는 docs/ops/evidence/professor-summary-gap-deploy-2026-08-29.json이다.
래스터만 사용이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.
기능 우선메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.
diff --git a/docs/guides/testing.md b/docs/guides/testing.md
index 1d05cb5..349bb07 100644
--- a/docs/guides/testing.md
+++ b/docs/guides/testing.md
@@ -98,6 +98,7 @@ python -m pytest engine_gateway/ --collect-only -q
| REQ-007 | session persistence/evaluation 관련 API 9 files, live/session 묶음, 실제 DB persistence E2E | 163 + 50 pytest, DB E2E 1 passed — 실패한 옛 평가 뒤 새 회기 가능 |
| REQ-008 | `app/test_engine_health_contract.py`와 session stream 회귀 | health contract 1 passed; incomplete EOF는 live/session 50 묶음에 포함 |
| 학습자 성장 패널 헤더 | `uc-learner-home-dashboard.spec.ts --grep "성장 지표 라포 헤더"` + `check:design-ssot` + `check:cosmetic-filter-safety` + typecheck | chromium desktop/mobile 2 passed — 선택된 라포 문구의 부모는 plain `div`, 배경 transparent·border/radius/padding 0이며 주변 panel 구조는 유지 |
+| 교수자 검토·요약 카드 간격 | `full-sweep-professor.spec.ts --grep "renders six KPI cards"` + `layout-visual-gate.spec.ts` + `session-layout.spec.ts` | 기존 0px에서 회귀 게이트 RED를 확인하고 `--sp-3`=12px로 교정했다. focused 1 passed, 7폭 교수자 gate 1 passed, 전체 layout visual 15 passed, session 무회귀 8 passed. Pages `0c60261e…` 승격 뒤 실제 `/teach`는 computed/실측 12px, overflow 0, console warning/error 0이다. |
| REQ-001 공개 운영 | `https://vignette.chanpaca.net/login` + Google account chooser/callback | `allowed_email_domains=[]`이며 기존 일반 Google 계정 callback→`/admin` 성공으로 가입 범위는 확인했다. Pages production `ef48c0ae…` 승격 뒤 custom domain은 단일 `Google 계정으로 로그인` CTA 1개·구 계정 선택 버튼 0·dev login 0·console warning/error 0이고 격리 Playwright OAuth 시작 검증 **1 passed**다. 실제 Gmail callback과 복구 계정의 `/admin`·기존 데이터 확인 전에는 검토를 유지한다. |
| Google 계정 데이터 복구 | migration 19, alias/auth focused, 전체 API·gateway, 백업 복제 DB, 활성 DB·공개 API | Gmail의 빈 중복 사용자와 canonical 관리자 계정을 이메일 자동병합 없이 명시적 Google subject 별칭 2개로 연결했다. 정식 계정 21회기·64턴·평가 6건과 Gmail 원본 설정 1행을 보존하고 source-only 알림 키를 canonical 설정에 무손실 병합했다. Gmail 옛 세션 1개 철회, 중복 계정 suspended, 감사로그 1건, 사용자 1175·회기 469·평가 65와 고아 0을 확인했다. API+gateway **1111 passed/1 skipped**, release agent **31 passed**, 백업 복제 DB 트랜잭션·cleanup 및 런타임 DB 역할 alias SELECT를 통과했다. 실제 Gmail OAuth callback은 사용자 계정 선택 후 최종 확인한다. |
| REQ-005·007·008 공개 운영 | P20 회기 `03dddadd-adf3-4922-acbf-31002470da52` | 생성→자기점검 원장 잠금→실제 학습자/AI 내담자 2턴→종료→AI 평가 완료→P20 1회 기록 영속→다음 회기 버튼 재노출 |
diff --git a/docs/ops/evidence/professor-summary-gap-deploy-2026-08-29.json b/docs/ops/evidence/professor-summary-gap-deploy-2026-08-29.json
new file mode 100644
index 0000000..928ee87
--- /dev/null
+++ b/docs/ops/evidence/professor-summary-gap-deploy-2026-08-29.json
@@ -0,0 +1,67 @@
+{
+ "schema": "vignette.professor-summary-gap-deploy.v1",
+ "status": "deployed_and_verified",
+ "captured_at_utc": "2026-08-29T07:45:15.5483426Z",
+ "source": {
+ "commit": "5bf89ff4ee971940882695d27f153e1460df295e",
+ "tree": "29f76aeb37d911a6947f96020719826f606f9c58",
+ "author": "Yun Chan",
+ "clean_worktree": "D:/workspace/vignette-web-gap-5bf89ff4",
+ "tracked_clean": true
+ },
+ "change": {
+ "route": "/teach",
+ "container": ".pf-signal-strip",
+ "upper_surface": ".pf-triage",
+ "lower_surface": ".pf-kpis[aria-label='교수자 요약']",
+ "previous_gap_px": 0,
+ "current_gap_token": "--sp-3",
+ "current_gap_px": 12,
+ "new_color_or_motion_tokens": false
+ },
+ "verification": {
+ "regression_gate_red": "passed: gap 0 produced expected failure with 12px deviation",
+ "focused_professor_e2e": "1 passed",
+ "professor_seven_width_gate": "1 passed across 390, 720, 861, 900, 1024, 1280 and 1440px",
+ "full_layout_visual_gate": "15 passed",
+ "session_layout_regression": "8 passed",
+ "typecheck": "passed",
+ "design_ssot": "passed",
+ "lint": "passed",
+ "production_build": "passed",
+ "clean_build_runs": 2,
+ "clean_build_deterministic_file_count": 599
+ },
+ "asset_preservation": {
+ "origins_checked": 7,
+ "assets_added": 172,
+ "final_file_count": 771,
+ "previous_entry_status": 200
+ },
+ "deployment": {
+ "project": "vignette",
+ "environment": "production",
+ "branch": "main",
+ "deployment_id": "0c60261e-cb37-482d-ba42-d91586194c48",
+ "deployment_url": "https://0c60261e.vignette-b1q.pages.dev",
+ "custom_domain": "https://vignette.chanpaca.net",
+ "entry_asset": "assets/index-DIAUjzc_.js",
+ "entry_sha256": "c314ba616fcf96883d2eec21bcb147d61a5877dc3be450a68bb98df88b137ce2",
+ "professor_css_asset": "assets/Professor-BfR874KA.css",
+ "professor_css_sha256": "63dbe2c7fdeade573996200d0376ece04e5cfa514d33ed1f1ba73e4938ae7fff",
+ "custom_and_preview_assets_match_clean_build": true,
+ "custom_teach_status": 200
+ },
+ "runtime_browser": {
+ "url": "https://vignette.chanpaca.net/teach",
+ "viewport": {
+ "width": 1425,
+ "height": 1272
+ },
+ "computed_row_gap": "12px",
+ "rendered_gap_px": 12,
+ "horizontal_overflow_px": 0,
+ "console_warning_or_error_count": 0,
+ "visual_inspection": "passed"
+ }
+}