Files
document-haness/runs/keycloak/2026-09-16-2130-fact-redis-preference/run.json
T
DongHyeonkaandClaude Opus 5 2109f726fe feat(pipeline): keycloak-session-store 25편·virtualization 59편을 S3→S5→S6 으로 돌린다
기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만
있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문
종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다.

SSOT 결함 둘을 고쳤다.

- kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이
  「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽
  `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다.
- virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데
  원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다.

기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은
둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더
든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다).

계약을 셋 고쳤다.

- kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/**
  28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는
  것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온
  것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수
  대조했을 때 가장 가까운 커밋도 28개가 어긋났다).
- virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고
  재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다.
- kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고
  넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다.

style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져
(실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고,
engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고
있었다(Question 기록에서 11.94 → 3.86).

verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 11:01:55 +09:00

264 lines
13 KiB
JSON

{
"schemaVersion": 2,
"runId": "2026-09-16-2015",
"project": "keycloak",
"record": "docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"startedAt": "2026-09-16T20:15:53+09:00",
"finishedAt": "2026-09-16T20:35:36+09:00",
"stages": [
{
"id": "S1",
"name": "코드베이스 → SSOT",
"skill": "analyzing-codebase-for-tech-log",
"runBy": "ssot-analyst",
"status": "SKIPPED",
"skipReason": "SSOT(docs/keycloak/final/document.md)가 이미 있고 이 기록의 근거를 그 안에서 찾을 수 있다. 이번 런은 기록의 칸 배치를 고치는 것이라 SSOT 를 건드리지 않았다.",
"skillEcho": "",
"skillRevision": "edd45dfec66d155a621cd41186b83b5582f2244c",
"inputs": [],
"outputs": [],
"gates": [],
"notes": "",
"finishedAt": "2026-09-16T20:19:18+09:00",
"finishedBy": null
},
{
"id": "S2",
"name": "SSOT → 분해 계약",
"skill": "deriving-tech-log-root-tree",
"runBy": "tree-deriver",
"status": "SKIPPED",
"skipReason": "이 글감은 tech-log-tree.json 에 PROMOTE·CONFIRMED 로 이미 있다. 계약이 아니라 기록 파일 안의 문단 위치를 고쳤다.",
"skillEcho": "",
"skillRevision": null,
"inputs": [],
"outputs": [],
"gates": [],
"notes": "",
"finishedAt": "2026-09-16T20:19:18+09:00",
"finishedBy": null
},
{
"id": "S3",
"name": "글감 → 기록",
"skill": "writing-tech-log-records",
"runBy": "record-writer",
"status": "DONE",
"skipReason": "",
"skillEcho": "- 자료가 뒷받침하지 않는 선택 이유. 썼다는 사실을 왜 골랐는지로 바꾸지 않는다.",
"skillRevision": null,
"inputs": [],
"outputs": [
"docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md"
],
"gates": [
{
"cmd": "python3 scripts/studio-body.py docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md -o /tmp/sb.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:18+09:00"
},
{
"cmd": "node --experimental-transform-types .agents/skills/writing-tech-log-records/scripts/check_body.mjs /tmp/sb.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:18+09:00"
},
{
"cmd": "node .agents/skills/rewriting-technical-prose-naturally/scripts/check_prose.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:18+09:00"
},
{
"cmd": "node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs keycloak --repo",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:18+09:00"
},
{
"cmd": "python3 scripts/check-required-content.py --file docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:18+09:00"
},
{
"cmd": "node .agents/skills/writing-as-the-person-who-did-it/scripts/check_voice.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:19:19+09:00"
}
],
"notes": "사실 칸 47행의 「공유 저장소 후보로 Redis를 우선 보고 있지만 아직 고르지 않았다.」 한 줄을 지웠다. fact-reviewer 가 FAIL 로 판정했다 — SSOT 의 Redis 4회(241·581·853·1163)가 전부 부재 진술이고 선호를 말한 줄이 0건, SSOT 전문에 후보·우선·선호·유력이 한 건도 없다. 계약에도 Redis 가 0회이고 evidence 디렉터리는 존재 자체가 없다(못 본 것이 아니라 없다). 581·853 이 Redis 와 JDBC 를 동격으로 나열하는데 기록이 그 동격을 서열로 바꿨다. 같은 기록 미지수(어느 쪽이 맞는가)·다음 검증(후보마다 같은 입력으로 비교)·선택지(우세 없음) 셋과 충돌한다. git 이력상 2efb7ee 최초 커밋부터 있었고 4d50bb9 의 계약 채택 때 걸러지지 않았다. **이번 런의 앞 작업이 이 문장을 도입 산문에서 사실 불릿으로 승격시켜 등급을 올렸다** — 확인한 적 없는 것이 확인한 것들 사이에 끼었다. 고쳐 쓰지 않고 지운 이유는 「우선」만 빼면 미지수의 완전한 중복이 되고, SSOT 보강은 근거 제조이기 때문이다. 이음새는 손댈 자리가 없었고 선택지의 Redis 항목 넷은 그대로다. 저장소 전체 확인 grep 0건.",
"startedAt": null,
"generation": 1,
"owner": null,
"elapsedSeconds": 0,
"finishedAt": "2026-09-16T20:19:18+09:00",
"finishedBy": null
},
{
"id": "S4",
"name": "기록 → 그림",
"skill": "technical-visualizer",
"runBy": "diagram-maker",
"status": "SKIPPED",
"skipReason": "그림이 필요 없다. 이번 런은 제목 아래 문단을 알맞은 칸으로 옮기거나 지운 것이라 새로 그릴 소재가 생기지 않았다.",
"skillEcho": "",
"skillRevision": "edd45dfec66d155a621cd41186b83b5582f2244c",
"inputs": [],
"outputs": [],
"gates": [],
"notes": "",
"finishedAt": "2026-09-16T20:19:18+09:00",
"finishedBy": null
},
{
"id": "S5",
"name": "AI 티 제거",
"skill": "rewriting-technical-prose-naturally",
"runBy": "prose-rewriter",
"status": "DONE",
"skipReason": "",
"skillEcho": "- Do not shorten merely to look more human.",
"skillRevision": null,
"inputs": [],
"outputs": [
"docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md"
],
"gates": [
{
"cmd": "node .agents/skills/rewriting-technical-prose-naturally/scripts/check_prose.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:30:49+09:00"
},
{
"cmd": "node .agents/skills/rewriting-technical-prose-naturally/scripts/style_profile.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 1,
"session": null,
"generation": 1,
"at": "2026-09-16T20:30:49+09:00"
},
{
"cmd": "node --experimental-transform-types .agents/skills/writing-tech-log-records/scripts/check_body.mjs /tmp/s5.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:30:49+09:00"
},
{
"cmd": "node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs keycloak --repo",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:30:49+09:00"
}
],
"notes": "두 곳, 둘 다 사실 칸. (1) 43행 「조회하고」→「조회하지만」 — 다음 줄이 「두 저장 구조를 각각 따로 설계해야 한다」인데 ~하고 로 이으면 왜 따로 설계해야 하는지가 문장에서 끊긴다. 대비는 지어낸 게 아니다 — 관계 칸이 「찾는 열쇠가 다르다는 사실의 출처다」라고 적고 HEAD 판도 「찾지만 … 찾는다」였다. (2) 47행 「학습 환경을」→「학습 환경에서」 — 전자는 학습 환경 자체를 확인했다로 읽히는데 확인한 것은 위 항목들이고 학습 환경은 그 자리다. 지운 자리의 이음새는 손대지 않았다 — 앞뒤가 「가능성 → 아직 실행으로 확인 못 함」으로 그대로 이어져 메울 문장이 필요 없었다. style_profile 의 벗어남 1건(독자 안내 17.5)은 오탐이다 — 정규식이 「공유」를 독자 안내로 세는데 매치 7건 중 5건이 「저장소를 공유한다」이고 둘은 시간 순서의 「먼저」다. 독자에게 말을 거는 문장은 이 기록에 하나도 없고, 밴드에 넣으려면 「공유」를 지워야 하는데 그건 사실을 고치는 것이다.",
"startedAt": null,
"generation": 1,
"owner": null,
"elapsedSeconds": 0,
"finishedAt": "2026-09-16T20:30:49+09:00",
"finishedBy": null
},
{
"id": "S6",
"name": "일한 사람의 목소리",
"skill": "writing-as-the-person-who-did-it",
"runBy": "voice-writer",
"status": "DONE",
"skipReason": "",
"skillEcho": "- 확인하지 못한 것이 **목록**으로 있고, 그것이 걸리는 대목에는 없다",
"skillRevision": "edd45dfec66d155a621cd41186b83b5582f2244c",
"inputs": [],
"outputs": [
"docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md"
],
"gates": [
{
"cmd": "node .agents/skills/writing-as-the-person-who-did-it/scripts/check_voice.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:35:36+09:00"
},
{
"cmd": "node .agents/skills/rewriting-technical-prose-naturally/scripts/check_prose.mjs docs/keycloak/tech-log-studio/oauth-oidc-auth-boundary/question/question-bff-state-store.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:35:36+09:00"
},
{
"cmd": "node --experimental-transform-types .agents/skills/writing-tech-log-records/scripts/check_body.mjs /tmp/s6.md",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:35:36+09:00"
},
{
"cmd": "node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs keycloak --repo",
"exit": 0,
"session": null,
"generation": 1,
"at": "2026-09-16T20:35:36+09:00"
}
],
"notes": "둘을 넣었고 Redis 선호는 되살리지 않았다. (1) 사실 첫 항목에 어긋난 자리 — JavaScript 응답에 토큰이 안 보였을 때는 토큰 다루는 일도 사라진 줄 알았는데 BFF 코드를 따라가 보니 세션에서 Authorized Client 를 찾아 액세스 토큰을 붙여 내부 API 를 대신 부르고 있었다. 근거 SSOT:169, source 앵커 안. 문단을 칸으로 가르는 동안 사실 첫 항목이 「상태는 둘이다」 평서문만 남아 그 둘을 어떻게 찾았는지가 사라졌었다. SSOT 의 1인칭 「제가」는 안 옮기고 한다체 무주어로 뒀다. (2) 제약 셋째 항목에 「이 학습 환경에서는 처리량을 재지 못해 어느 지점부터 느려지는지 숫자로 말할 수 없다」 — 근거 SSOT:105. 성능 주장이 제약 칸에 맨몸으로 서 있었고 인정은 사실 끝에만 있어 걸리는 대목에는 없었다. SSOT:105 가 같이 묶은 「장애 복구 시간」은 뺐다 — 계약에서 그 칸은 형제 글감의 unknown 이라 끌어오면 주제가 겹친다. **지운 Redis 자리는 안 채웠다** — 「아직 못 골랐다」는 흔적이 questionStatus OPEN · 제목 · 요약 · 미지수 첫 항목 · 다음 검증 마지막에 이미 제자리로 들어가 있다. 흔적 없음이 아니라 흔적이 이미 있음이고, 한 줄 더 쓰면 방금 지운 선호로 되돌아가는 가장 쉬운 길이다. 근거 재확인도 0건 — Redis 4회 전부 부재 진술, 계약에 Redis 문자열 없음, evidence 디렉터리 없음, 커밋 3건에 저장소 선택을 말한 메시지 없음.",
"startedAt": null,
"generation": 1,
"owner": null,
"elapsedSeconds": 0,
"finishedAt": "2026-09-16T20:35:36+09:00",
"finishedBy": null
},
{
"id": "S7",
"name": "Studio 저장",
"skill": "publishing-tech-log-to-studio",
"runBy": "studio-validator",
"status": "SKIPPED",
"skipReason": "사용자가 Studio 반입을 요청하지 않았다. 이 기록은 이미 게시돼 있고 S7 은 저장까지인데, 저장하면 Studio 쪽 version 이 올라간다. 저장소와 공개본이 갈린 상태로 두고 사람이 판단할 일로 넘긴다. 게시는 어떤 경우에도 하지 않는다.",
"skillEcho": "",
"skillRevision": null,
"inputs": [],
"outputs": [],
"gates": [],
"notes": "",
"finishedAt": "2026-09-16T20:35:36+09:00",
"finishedBy": null
}
],
"revision": 24,
"updatedAt": "2026-09-16T20:35:36+09:00",
"sessions": [
{
"session": null,
"stage": "S3",
"generation": 1,
"beganAt": "2026-09-16T20:19:18+09:00"
},
{
"session": null,
"stage": "S5",
"generation": 1,
"beganAt": "2026-09-16T20:30:49+09:00"
},
{
"session": null,
"stage": "S6",
"generation": 1,
"beganAt": "2026-09-16T20:35:36+09:00"
}
]
}