docs: 계약 없이 남아 있던 두 프로젝트에 주제를 갈라 계약을 세운다

keycloak-session-store 와 TechLog 는 SSOT 만 있고 분해 계약이 없었다. 두 프로젝트
모두 후보를 처분과 함께 남기고 PROMOTE 만 주제로 올린다.

  keycloak-session-store  주제 6 · 글감 33 · 후보 42 (제외 9)
  TechLog                 주제 13 · 글감 56 · 후보 91 (제외 35)

TechLog 는 저장소가 셋이라 sourceRepository 를 목록으로 적는다. 설계 패키지는 이
기계에 체크아웃이 없고 반입한 쪽의 MANIFEST.sha256 이 세 계약의 원본 리비전을
고정하므로 그것을 리비전으로 적었다. 검사기 둘이 그 모양을 읽게 고친다 —
verify-tech-log-tree.py 는 목록의 항목마다 path·revision·verified 를 보고,
check_evidence.mjs 는 체크아웃이면 git 으로, 매니페스트면 그 파일이 리비전을
적고 있는지로 대조한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-07 13:30:12 +09:00
co-authored by Claude Opus 5
parent 4d50bb939a
commit a0ca2bb72a
4 changed files with 4028 additions and 34 deletions
+17 -10
View File
@@ -142,20 +142,27 @@ def verify(project: str) -> Report:
"— 칸마다 error 를 내지 않는 대신 미채택 자체를 여기서 한 번 센다")
# ── 분석한 저장소 ──────────────────────────────────────────────
# 저장소가 여럿인 프로젝트는 목록으로 적는다. 하나면 객체 하나로 적어도 된다
repo = index.get("sourceRepository") or {}
repos = repo if isinstance(repo, list) else [repo]
if has_contract:
if not repo.get("path"):
if not repos:
rep.error("sourceRepository.path 가 없다",
f"{project}: 어느 저장소를 읽고 쓴 글인지 적혀 있지 않다")
elif not os.path.isdir(repo["path"]) and "://" not in repo["path"]:
rep.warn("sourceRepository.path 가 이 기계에 없다", repo["path"])
# 갈래가 여럿이면 단일 커밋으로 표현되지 않는다. revisions 로 적는다
if not repo.get("revision") and not repo.get("revisions"):
rep.warn("sourceRepository 에 리비전이 없",
f"{project}: 문서가 서술한 상태의 커밋을 고정하지 않았다")
elif not repo.get("verified"):
rep.warn("sourceRepository.verified 가 없다",
f"{project}: 그 리비전이 맞다고 판단한 근거가 없다")
for r in repos:
name = r.get("name") or project
if not r.get("path"):
rep.error("sourceRepository.path 가 없다",
f"{project}: 어느 저장소를 읽고 쓴 글인지 적혀 있지 않")
elif not os.path.exists(r["path"]) and "://" not in r["path"]:
rep.warn("sourceRepository.path 가 이 기계에 없다", f"{name}: {r['path']}")
# 갈래가 여럿이면 단일 커밋으로 표현되지 않는다. revisions 로 적는다
if not r.get("revision") and not r.get("revisions"):
rep.warn("sourceRepository 에 리비전이 없다",
f"{project}/{name}: 문서가 서술한 상태의 커밋을 고정하지 않았다")
elif not r.get("verified"):
rep.warn("sourceRepository.verified 가 없다",
f"{project}/{name}: 그 리비전이 맞다고 판단한 근거가 없다")
# ── 후보를 찾는 범위 ───────────────────────────────────────────
scope = index.get("candidateScope") or {}