From 4a2582155200261178df0f26396b342aa20ae92d Mon Sep 17 00:00:00 2001 From: jun0 Date: Fri, 4 Sep 2026 00:12:09 +0900 Subject: [PATCH 1/2] docs: mandate the round worklog in the DoD; run its lock locally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 운영자 채택 제안 2건(2026-08-26-worklog-json-proposals-convention#p0·#p1)을 한 회차로 처리했다. 코드(.rs) 변경 0 · 새 도구 0 · CI 워크플로 무접촉. #p0 결정 = 의무화한다. 먼저 쟀다 — 규약 착지(b3a4cf4 · 2026-08-26) 이후 착지 4회차 중 3건(75%)이 쌍을 남겼고, 유일한 미작성(PR #13)은 부모가 정확히 b3a4cf4 라 규약을 알 수 없었던 회차다(알 수 있었던 회차만 3/3). 관측이 높은데도 의무화한 이유는 실패가 조용하고 잠글 수 없기 때문이다 — 잠금은 존재하는 .json 만 검사하므로(비소급 설계) 아예 안 쓴 회차는 red 0 · 카드만 0 이다. 표본 3건 · 전건 같은 리니지. 되돌릴 수를 AGENTS.md 에 측정 명령과 함께 박았다(10회차 착지 시점 재측정 · 미작성 ≥2 면 문안을 빼거나 기계 강제로 · 열린 카드 <5 면 의무 재검토 · 오늘 기준선 5). #p1 = 잠금이 rust.yml:63 worklog_json job 한 곳에서만 돌았다. CLAUDE.md DoD green 줄에 4번째 명령으로 붙였다. cargo test 안으로 넣는 두 경로는 기각 — serde_json 은 Cargo.lock 에 부재(새 의존성 + 6셀 빌드), python3 shell-out 은 python 없는 머신에서 오탐 red. 3명령은 한 글자도 안 건드렸다 ⇒ 기존 검사 오탐 위험 구조적으로 0. 대가: 잠금 중앙값 0.10s = 재컴파일 회차 +0.17% · 완전 캐시 회차 +1.1%(최악 약 1%). --- AGENTS.md | 31 ++++- CLAUDE.md | 6 +- REPORT.md | 30 +++++ STATE.md | 14 +++ ...-09-04-worklog-mandate-and-local-gate.json | 46 +++++++ ...26-09-04-worklog-mandate-and-local-gate.md | 116 ++++++++++++++++++ 6 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json create mode 100644 docs/worklog/2026-09-04-worklog-mandate-and-local-gate.md diff --git a/AGENTS.md b/AGENTS.md index 489754ef..81b20f75 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,7 +49,36 @@ the consumer does not read them, so they are for humans and the next round. **No retroactive conversion.** The convention applies to new rounds only; the lock asks only "if a `.json` exists, is it well-formed and does it have its `.md` sibling" — it never demands a `.json` for an existing `.md`. Lock: `scripts/check-worklog-json.py`, run by the `worklog_json` -CI job (`cargo test` does not cover docs). +CI job **and by the local DoD** (`CLAUDE.md` §Definition of Done — 4th command; `cargo test` does +not cover docs, so it stays a plain script). + +**Mandatory since 2026-09-04** (decision, not a habit): a round that writes 후속 추천 into +`REPORT.md` also writes the `docs/worklog/` pair. Rationale — the failure is **silent and +unlockable**: the lock only validates a `.json` that *exists*, so a round that skips it produces +zero cards with no error anywhere. Measured before deciding: of the **4 rounds landed since the +convention itself landed** (`b3a4cf4`, 2026-08-26 → `origin/main`), **3 wrote the pair (75%)**; +the one miss (PR #13) branched off *before* the convention, so among rounds that could have known +it is **3/3**. The mandate costs one line and converts an observed habit (n=3, all one lineage) +into a checked one. + +**Revert numbers — recount at the 10th round landed after 2026-09-04.** Do not re-argue this +from taste; re-measure: + +```sh +# ⒜ 미작성 회차: 착지 회차 중 worklog 쌍이 없는 것 +for c in $(git rev-list --first-parent <2026-09-04-이후-첫-착지>..origin/main); do + git diff --name-only "$c^1" "$c" | /usr/bin/grep -q '^docs/worklog/' || echo "$c no-worklog"; done +# ⒝ 열린 카드 수: proposals 총합 − (adopted + declined) +python3 -c "import json,glob;p=a=0 +for f in glob.glob('docs/worklog/*.json'): + d=json.load(open(f));p+=len(d.get('proposals',[]));a+=len(d.get('adoptedProposals',[]))+len(d.get('declinedProposals',[])) +print('open cards:',p-a)" +``` + +- ⒜ **≥ 2 (>20%)** ⇒ DoD 에 적어도 안 지켜진다는 뜻이다. 문안을 **빼거나** 기계 강제로 올려라 — + 문서에만 둔 채로 유지하지 마라(그 상태가 가장 나쁘다: 규칙은 있고 효력은 없다). +- ⒝ **< 5** ⇒ 의무화해도 카드가 늘지 않았다는 뜻이므로 **의무 자체를 재검토**하라. + Baseline measured 2026-09-04: 9 proposals − 4 disposed = **5 open**. So ⒝ means "fewer than today". ## Testing Boundaries - Keep `java_runtime/tests/classes` limited to Java standard library class and API behavior. - Test JVM and interpreter semantics, including class initialization, bytecode execution, and monitor behavior, with compiled Java fixtures under `test_data/src` and expected output under `test_data`, executed by `tests/test_class.rs`. diff --git a/CLAUDE.md b/CLAUDE.md index c6e479d8..d4737488 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,8 +22,12 @@ **검증기로 막을 수 없다.** ⇒ 이 조항은 **1차 방어**이며 **최종 방어는 diff 검토**다. ## Definition of Done -- `cargo fmt --check` · `cargo clippy` · `cargo test` 전부 green(명령 상세 = `AGENTS.md`). +- `cargo fmt --check` · `cargo clippy` · `cargo test` · `python3 scripts/check-worklog-json.py` + 전부 green(명령 상세 = `AGENTS.md`). - 착수·완료마다 STATE.md 의 "진행중/완료/다음" 을 갱신하고, 완료 시 REPORT.md 상단에 `[YYYY-MM-DD]` 요약 3줄(무엇을·왜·사용자 영향) + 후속 추천을 append 한다. +- ★**후속 추천을 적었으면 `docs/worklog/YYYY-MM-DD-.{md,json}` 한 쌍도 남긴다** — + `.json` 이 없으면 그 추천은 cockpit 「후속 작업 추천」 패널에 **구조적으로 도달하지 못한다** + (규약·되돌릴 수 = `AGENTS.md` §Round Worklog). - ★작업 티켓의 **완주 지점 = PR 오픈**이다. 머지는 게이트② 검수자가 approve 와 같은 턴에 집행한다(`-merge` 는 예외 경로) (`main` 직push 0 — `AGENTS.md` §Git Workflow). diff --git a/REPORT.md b/REPORT.md index cce6198b..4b1f708c 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,5 +1,35 @@ # REPORT +## [2026-09-04] 워크로그 의무화 «결정» + 형식 잠금을 로컬 DoD 안으로 (rustjava-worklog-mandate-decision-and-local-gate) +- 무엇을: 운영자 채택 제안 2건을 한 회차로 처리했다. ⑴**워크로그 작성을 DoD 의무로 «결정»** + (`CLAUDE.md` 1줄 + `AGENTS.md` 포인터) ⑵**형식 잠금 `python3 scripts/check-worklog-json.py` 를 + 로컬 DoD 4번째 명령으로 편입**. ★**코드(`.rs`) 변경 0 · 새 도구 0 · CI 워크플로 무접촉.** +- 왜: ★**먼저 쟀다** — 규약 자신이 착지한 `b3a4cf4`(2026-08-26) 이후 착지한 **4회차 중 3건(75%)**이 + 워크로그 쌍을 남겼고, 유일한 미작성(PR #13)은 **부모가 정확히 `b3a4cf4`** 라 규약을 알 수 없었던 + 회차다(알 수 있었던 회차만 세면 **3/3**). ★★**관측이 높은데도 의무화를 고른 이유는 하나다 — + 실패가 «조용하고 잠글 수 없다».** 잠금은 **존재하는 `.json` 만** 검사하므로(규약 비소급 설계) + 아예 안 쓴 회차는 **어디서도 red 가 나지 않고 카드만 0** 이 된다. 표본은 3건이고 전건 같은 + 리니지라 소형 회차 관측은 **0** 이다. ⇒ 대가 DoD 1줄로 **무방비한 침묵**을 닫았다. + ★**잠금 위치 실측**: `.github/workflows/rust.yml:63` `worklog_json` job **단 1곳**(ubuntu 1러너) — + 6셀 매트릭스에도 로컬 3명령에도 없어 **틀린 파일은 PR 을 열어야 빨개졌다.** +- 사용자 영향: 런타임 동작 **무변경**. 회차가 남긴 후속 추천이 cockpit 「후속 작업 추천」 패널에 + **빠짐없이 도달**하고, 형식 오류를 **push 전에** 알게 된다. +- 검증: ★**변경 «적용 후»** 4명령 전건 **rc=0**(재컴파일 회차 `fmt` 1.1s · `clippy` 11.5s · + `test --all` 47.6s / 완전 캐시 회차 0.56s · 0.39s · 8.41s · 잠금 0.04s). + ★**3명령은 한 글자도 안 건드렸다** ⇒ 기존 검사의 오탐 위험은 **구조적으로 0**. + ★**대가(초) — 분모를 둘 다 적는다**: 잠금 5회 `0.10·0.04·0.13·0.13·0.08` ⇒ 중앙값 **0.10s**. + 재컴파일 회차(60.2s) 대비 **+0.17%** · ★**완전 캐시 회차(9.36s) 대비 +1.1%** ⇒ **최악 약 1%**. +- ★**`cargo test` «안»으로 넣지 않았다 — 두 경로 다 기각**: `serde_json` 은 ★**`Cargo.lock` 에 없어** + 새 의존성 + 6셀 빌드 비용이고(★스크립트 docstring 이 이미 같은 이유로 기각한 길) · `python3` + shell-out 은 python 없는 머신에서 `cargo test` 를 **red** 로 만들어 「오탐 0」 절대 조건을 깬다. +- ★★**되돌릴 «수» — `AGENTS.md` §Round Worklog 에 측정 명령과 함께 박았다**(취향으로 재론하지 말고 다시 재라): + **2026-09-04 이후 10회차 착지 시점**에 ⒜**미작성 회차 ≥ 2(>20%)** ⇒ 문안을 **빼거나** 기계 강제로 올려라 + (★문서에만 둔 채 유지하지 마라 — 규칙은 있고 효력은 없는 상태가 가장 나쁘다) · + ⒝**열린 카드 < 5** ⇒ **의무 자체를 재검토**. +- ★**후속 추천**: 워크로그 **미작성**을 «기계»로 잡을지 판정하라 — 지금 의무는 **문서에만** 있다 + (잠금은 「있으면 검사」라 「없으면 침묵」이다). 판단 재료 = 워크로그 `2026-09-04-…json` `proposals[0]`. +- ★**고지**: 열린 **PR #19** 와 `REPORT.md`·`STATE.md` **상단이 겹친다** — 나중에 착지하는 쪽이 인접 충돌한다. + ## [2026-08-27] upstream 동기 근인 확정 — 게이트③ `--squash` 가 계보를 버린다 (rustjava-upstream-sync-squash-defeats-convergence) - 무엇을: S1~S4(PR #11·#13·#16·#17)가 **전건 `merged=true`** 인데도 `merge-base origin/main upstream/main` 이 fork 시점 **`62cf0c6a`** 그대로이고 behind **33** 이 줄지 않던 근인을 확정했다. 근인은 게이트③ diff --git a/STATE.md b/STATE.md index 4ef328a5..78b954cf 100644 --- a/STATE.md +++ b/STATE.md @@ -1,6 +1,20 @@ # STATE ## 진행중 +- [rustjava-worklog-mandate-decision-and-local-gate] ★**워크로그 작성을 DoD «의무»로 결정 + 형식 잠금을 + 로컬 DoD 4번째 명령으로 편입.** ★**코드 변경 0 · 새 도구 0 · CI 워크플로 무접촉.** + ★**먼저 쟀다**: 규약 착지(`b3a4cf4` · 2026-08-26) 이후 착지 **4회차 중 3건(75%)** 작성 · + 유일한 미작성(PR #13)은 **부모가 정확히 `b3a4cf4`** 라 규약을 알 수 없었다(알 수 있었던 회차만 **3/3**). + ★★**관측이 높은데도 의무화한 이유 = 실패가 «조용하고 잠글 수 없다»** — 잠금은 **존재하는 `.json` 만** + 검사하므로(비소급 설계) 아예 안 쓴 회차는 **red 0 · 카드만 0** 이다. 표본 3건 · 전건 같은 리니지. + ★**되돌릴 수**(`AGENTS.md` §Round Worklog · 측정 명령 동봉): **10회차 착지 시점** 재측정 — + ⒜미작성 ≥ 2 ⇒ 문안을 빼거나 **기계 강제로** ⒝열린 카드 < 5 ⇒ **의무 재검토**. + ★**`cargo test` 안으로 안 넣었다**: `serde_json` 이 `Cargo.lock` 에 **부재**(새 의존성 + 6셀 빌드) · + `python3` shell-out 은 python 없는 머신에서 **오탐 red** ⇒ 「오탐 0」 절대 조건 위반. + 대가 = **+0.10s**(3명령 warm 합계 60.2s 대비 **+0.17%**). **PR 대기 — 게이트③ 미착지.** +- [rustjava-upstream-sync-remeasure-s5-s7-and-lock-restore-basis] ★**PR #18 착지 뒤 기준 S5~S7 재측정 + + 「충돌 수에 base 병기」를 §5 상시 규칙으로 채택**(PR **#19** 대기). 같은 컷 `ba5797b` 가 + **19 · 112 · 4** 로 갈린다 · 새 충돌 **S5 +3 · S6 +0 · S7 +1** · ★**S8 이 필요하다**(개명 스윕). - [rustjava-upstream-sync-squash-defeats-convergence] ★**S1~S4 가 착지하고도 fork 가 upstream 에 한 걸음도 가까워지지 않은 근인을 확정하고 계보를 기록했다.** 근인 = 게이트③ 제품 repo **`--squash`**. 증명은 **머지커밋 부모 수**다 — `6bfe97c4`·`11ef5010`·`4bb796de`·`3a597768` **전건 1개**(커밋 7·10·15·21이 diff --git a/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json new file mode 100644 index 00000000..f7bb9cca --- /dev/null +++ b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json @@ -0,0 +1,46 @@ +{ + "schema": 1, + "date": "2026-09-04", + "title": "워크로그 작성을 DoD 의무로 «결정» + 형식 잠금을 로컬 DoD 4번째 명령으로 편입", + "services": [ + "RustJava" + ], + "taskId": "rustjava-worklog-mandate-decision-and-local-gate", + "summary": "운영자 채택 제안 2건(#p0 의무화 결정 · #p1 잠금이 로컬에서 안 돈다)을 한 회차로 처리했다. #p0 — 먼저 쟀다: 규약 착지(b3a4cf4 · 2026-08-26) 이후 착지한 4회차 중 3건(75%)이 워크로그 쌍을 남겼고, 유일한 미작성 PR #13 은 부모가 정확히 b3a4cf4 라 규약을 알 수 없었던 회차다(알 수 있었던 회차만 세면 3/3). 관측이 높은데도 «의무화»를 골랐다 — 실패가 조용하고 잠글 수 없기 때문이다: 잠금은 존재하는 .json 만 검사하므로 아예 안 쓴 회차는 어디서도 red 가 안 나고 카드만 0 이 된다. 표본은 3건이고 전건 같은 리니지(upstream-sync)라 소형 회차 관측은 0 이다. 되돌릴 수를 AGENTS.md 에 박았다(2026-09-04 이후 10회차 착지 시점 재측정 · 미작성 ≥2 면 문안을 빼거나 기계 강제로 · 열린 카드 <5 면 의무 재검토 · 측정 명령 2개 동봉). #p1 — 잠금은 rust.yml:59-63 worklog_json job(ubuntu 1러너)에서만 돌고 6셀 매트릭스에도 로컬 3명령에도 없었다. CLAUDE.md DoD green 줄에 4번째 명령으로 붙였다. cargo test 안으로 넣는 두 경로는 기각: serde_json 은 Cargo.lock 에 없어 새 의존성 + 6셀 빌드 비용이고(스크립트 docstring 이 이미 같은 이유로 기각한 길), python3 shell-out 은 python 없는 머신에서 cargo test 를 red 로 만들어 「오탐 0」 절대 조건을 깬다. 3명령은 한 글자도 안 건드렸다.", + "changes": [ + "CLAUDE.md §Definition of Done — green 줄에 `python3 scripts/check-worklog-json.py` 를 4번째 명령으로 추가(#p1) + 「후속 추천을 적었으면 docs/worklog/ 쌍도 남긴다」 1줄 추가(#p0). 그 이상 늘리지 않았다.", + "AGENTS.md §Round Worklog — 잠금이 CI job «과 로컬 DoD» 양쪽에서 돈다고 갱신 + 「Mandatory since 2026-09-04」 결정 기록(측정한 수·근거) + 되돌릴 수 2종과 그것을 재는 명령 2개.", + "docs/worklog/2026-09-04-worklog-mandate-and-local-gate.{md,json} 신설.", + "STATE.md · REPORT.md 갱신." + ], + "deploy": { + "sha": "", + "urls": [] + }, + "verification": "측정 창 = 규약 착지 커밋 b3a4cf4(2026-08-26 11:57 KST · PR #15) 이후 origin/main 착지 회차 전건. 각 착지커밋에 대해 git diff --name-only ^1 에서 docs/worklog/ 를 센 결과: 11ef501(S2/#13) 0 · 4bb796d(S3/#16) 2 · 3a59776(S4/#17) 2 · 8c1238b(계보/#18) 2 ⇒ 3/4 = 75%. ★머지커밋 8c1238b 는 git show --name-only 로는 0 으로 보인다(머지커밋 기본 동작) — ^1.. 로 재야 2 가 나온다. 미작성 11ef501 의 부모는 정확히 b3a4cf4 ⇒ 규약보다 먼저 갈라진 브랜치라 알 수 없었다(알 수 있었던 회차만 3/3). 잠금 위치: /usr/bin/grep -rn check-worklog-json → .github/workflows/rust.yml:63 단 1곳(worklog_json job, ubuntu-latest 1러너). serde_json 부재 실측: Cargo.lock 에 name = \"serde_json\" 0건. 오탐 0 실증(현 main · warm): cargo fmt --all -- --check rc=0 1.1s · cargo clippy --all -- -D warnings rc=0 11.5s · cargo test --all rc=0 47.6s · python3 scripts/check-worklog-json.py rc=0. ★변경 적용 «후» 재실행도 4명령 전건 rc=0(완전 캐시: 0.56/0.39/8.41s + 잠금 0.04s). 대가 실측 5회: 0.10/0.04/0.13/0.13/0.08s ⇒ 중앙값 0.10s. ★분모를 둘 다 적는다 — 재컴파일 회차 합계 60.2s 대비 +0.17% · 완전 캐시 회차 합계 9.36s 대비 +1.1% ⇒ 최악 약 1%. 되돌릴 수 ⒝ 기준선: proposals 9 − 처분 4 = 열린 카드 5(= 「오늘보다 줄었으면」).", + "issues": [ + "★잠금은 «존재하는 .json 만» 검사한다(규약이 소급하지 않으므로 설계상 그렇다) ⇒ 워크로그를 아예 안 쓴 회차는 어디서도 red 가 안 난다. 이번 의무화는 그 침묵을 문서 규율로만 덮은 것이고 «기계 강제»는 아니다. 되돌릴 수 ⒜가 2건 이상이면 기계 강제로 올리라고 적어 둔 이유가 그것이다.", + "★관측 표본이 3건이고 전건 같은 리니지(upstream-sync)다. 규약 이전의 소형 회차(PR #8·#14 류)에 대한 관측은 0 이라 「소형 회차도 쓰는가」는 아직 모른다.", + "★대가는 시간이 아니라 「사람이 기억해야 하는 줄」이다(제안 ⑵ 자신이 적은 대가). 그 대가는 줄이지 못하고 그대로 치렀다 — DoD 명령이 3 → 4 다.", + "★열린 PR #19 와 REPORT.md·STATE.md 상단이 겹친다 — 둘 다 머리에 append 하므로 나중에 착지하는 쪽이 인접 충돌한다(내용 충돌 아님). 게이트③이 순서를 정할 때 알고 있어야 한다.", + "CI 워크플로는 무접촉이다 — worklog_json job 은 그대로 두었다(로컬 편입은 CI 를 대체하지 않는다. CI 는 여전히 머지 전 그물이다).", + "머지하지 않았다 — 게이트②·③은 별 세션이다. upstream(dlunch/RustJava) 발신 0." + ], + "proposals": [ + { + "title": "워크로그 미작성을 «기계»로 잡을지 결정하라 — 지금 의무는 문서에만 있다", + "plainSummary": "이번에 「회차마다 기록 파일을 남긴다」를 규칙으로 정했지만, 지키지 않아도 아무 경보가 울리지 않는다. 검사기는 «파일이 있을 때 형식이 맞는가»만 보지 «파일이 있는가»는 보지 않는다.", + "userBenefit": "후속 추천이 화면에서 빠지는 일이 사라진다 — 지금은 한 회차가 파일을 잊어도 아무도 모른 채 카드만 조용히 줄어든다.", + "why": "check-worklog-json.py 는 규약이 소급하지 않는다는 이유로 「존재하는 .json 만」 검사하도록 설계됐다(스크립트 docstring 에 명시). 그래서 이번 의무화는 CLAUDE.md 문안뿐이고 강제력이 없다. 실제로 규약 착지 후 4회차 중 1건이 미작성이었다(그 1건은 규약보다 먼저 갈라진 브랜치라 정상 참작되지만, 같은 형태가 다시 나면 구별할 방법이 없다).", + "tradeoff": "⑴PR 에 REPORT.md 변경이 있는데 docs/worklog/ 변경이 없으면 red — 정확하지만 CI 에 diff 판정 로직이 들어가고, 워크로그 없이 REPORT.md 만 고치는 정당한 회차(오타 수정 등)를 오탐한다. ⑵현상 유지면 문서 규율만 남고 침묵은 그대로다. ⑶되돌릴 수(10회차 재측정)를 먼저 돌려 보고 결정하면 판단 근거가 실측이 되지만 그만큼 늦다.", + "effort": "S — ⑴이면 worklog_json job 에 diff 판정 몇 줄. 판정 자체는 XS.", + "target": ".github/workflows/rust.yml · scripts/check-worklog-json.py · AGENTS.md §Round Worklog" + } + ], + "resolvedIssues": [], + "adoptedProposals": [ + "2026-08-26-worklog-json-proposals-convention#p0", + "2026-08-26-worklog-json-proposals-convention#p1" + ], + "declinedProposals": [] +} diff --git a/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.md b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.md new file mode 100644 index 00000000..60548136 --- /dev/null +++ b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.md @@ -0,0 +1,116 @@ +# [2026-09-04] 워크로그 의무화 «결정» + 잠금을 로컬 DoD 안으로 + +**티켓**: `rustjava-worklog-mandate-decision-and-local-gate` +**출처**: 운영자 채택 제안 2건 — `2026-08-26-worklog-json-proposals-convention#p0`(S) · `#p1`(XS) +**성격**: 문서 전용 · 코드 변경 **0** · 새 도구 **0** · CI 워크플로 **무접촉** + +--- + +## #p0 — 결정: **의무화한다** + +### ★먼저 쟀다 (「규약이 있으니 쓸 것이다」로 고르지 않았다) + +**측정 창**: 규약 자신이 착지한 커밋 `b3a4cf4`(2026-08-26 11:57 KST · PR #15) **이후** `origin/main` 에 +착지한 회차 전건. **그 앞은 셀 수 없다** — 규약이 존재하지 않았다. + +| 착지 커밋 | 회차 | worklog 쌍 | +|---|---|---| +| `11ef501` | S2 (PR #13) | ✗ **0** | +| `4bb796d` | S3 (PR #16) | ✓ 2 | +| `3a59776` | S4 (PR #17) | ✓ 2 | +| `8c1238b` | 계보 기록 (PR #18) | ✓ 2 | + +⇒ ★**4회차 중 3건 = 75%.** +★**유일한 미작성 `11ef501`(S2)의 부모는 정확히 `b3a4cf4` 다** — 즉 그 브랜치는 규약이 착지하기 **전에** +갈라져 나왔고 규약을 알 수 없었다. ⇒ ★**「알 수 있었던 회차」만 세면 3/3 = 100%.** +(참고: 현재 열린 PR #19 도 쌍을 갖는다. 착지 전이라 위 표에는 넣지 않았다.) + +### ★그런데도 «의무화»를 골랐다 — 이유 한 줄 + +★★**실패가 «조용하고 잠글 수 없기» 때문이다.** `check-worklog-json.py` 는 **존재하는 `.json` 만** 검사한다 +(규약이 소급하지 않으므로 설계상 그렇다). ⇒ 워크로그를 **아예 안 쓴** 회차는 **어디에서도 red 가 나지 않고** +카드만 0 이 된다. 관측치 75~100% 는 **표본 3건 · 전건 같은 리니지(upstream-sync)** 이고, +규약 이전의 소형 회차(PR #8·#14 류)에 대한 관측은 **하나도 없다.** +⇒ ★**「이미 잘 쓴다」는 관측만으로 무방비한 침묵을 남길 값이 없다. 대가는 DoD 1줄이다.** + +★**기각한 대안**: 「현상 유지(제안 ⑶)」 — 위 침묵을 그대로 둔다. +「`REPORT.md` 파싱 자동 생성(제안 ⑵)」 — ★이 리니지가 반복해 기각한 «파서 제2원본»이라 검토만 하고 버렸다. + +### ★★되돌릴 «수» — 형제 wie 리니지가 「기각을 되돌릴 수를 안 정했다」로 지적받았다. 같은 실수를 하지 않는다 + +**2026-09-04 이후 10회차가 착지한 시점에 다시 센다.** 정본은 `AGENTS.md` §Round Worklog 에 박았고 +**측정 명령 2개를 같이 넣었다**(취향으로 재론하지 말고 다시 재라는 뜻이다): + +- ⒜**미작성 회차 ≥ 2 (>20%)** ⇒ 「DoD 에 적어도 안 지켜진다」 ⇒ 문안을 **빼거나** 기계 강제로 올려라. + ★**문서에만 둔 채로 유지하지 마라** — 규칙은 있고 효력은 없는 상태가 가장 나쁘다. +- ⒝**열린 카드 < 5** ⇒ 의무화해도 카드가 늘지 않았다 ⇒ **의무 자체를 재검토**하라. + ★**기준선(2026-09-04 이 브랜치 실측)**: proposals 총 **9** − 처분 **4** = ★**열린 카드 5**. + ⇒ ⒝는 「**오늘보다 줄었으면**」이라는 뜻이다(임계를 오늘 값에 맞춰 박았다). + +--- + +## #p1 — 잠금을 로컬에서 도는 명령으로 + +### ★먼저 확인했다 — 「지금 어디서만 도는가」 + +- **CI 전용**: `.github/workflows/rust.yml:59-63` `worklog_json` job(`ubuntu-latest` 1러너) 한 곳뿐이다. + `rust_ci` 6셀 매트릭스(`:52-56`)에는 **없다.** +- **로컬 DoD 3명령**(`CLAUDE.md` §Definition of Done · 상세 `AGENTS.md` §Build/Test Commands): + `cargo fmt --check` · `cargo clippy` · `cargo test`. +- ⇒ ★**틀린 파일은 PR 을 열어야 비로소 빨개진다**(제안이 적은 그대로). + +### 처분 — DoD green 줄에 **4번째 명령**으로 붙였다 + +```diff +-- `cargo fmt --check` · `cargo clippy` · `cargo test` 전부 green(명령 상세 = `AGENTS.md`). ++- `cargo fmt --check` · `cargo clippy` · `cargo test` · `python3 scripts/check-worklog-json.py` ++ 전부 green(명령 상세 = `AGENTS.md`). +``` + +### ★★`cargo test` «안»으로 넣지 않은 이유 — 오탐 0 이 절대 조건이라서 + +두 경로를 다 검토하고 **둘 다 기각**했다: + +| 경로 | 기각 사유 | +|---|---| +| `serde_json` dev-dep + Rust 테스트(제안 ⑴) | `serde_json` 은 ★**`Cargo.lock` 에 없다**(실측) ⇒ 새 의존성 + **6셀 매트릭스** 빌드 시간. ★스크립트 자신의 docstring 이 이미 같은 이유로 기각한 길이다. Non-goal 「새 도구 0」과도 어긋난다. | +| Rust 테스트가 `python3` 를 shell-out | ★**오탐이 난다** — python3 없는 머신에서 `cargo test` 가 **red** 가 된다. 그것은 「기존 로컬 검사가 새로 red 가 되지 않는다」는 절대 조건 위반이다. | + +⇒ ★**3명령은 «한 글자도» 안 건드렸다.** 그래서 기존 검사의 오탐 위험은 **구조적으로 0** 이다 +(새 실패 모드는 4번째 명령 자신에만 붙는다). + +### 오탐 0 실증 — 4명령 전건 통과 (★변경 «적용 후» 다시 돌렸다) + +| 명령 | rc | ⓐ재컴파일 필요 | ⓑ완전 캐시 | +|---|---|---|---| +| `cargo fmt --all -- --check` | **0** | 1.1s | 0.56s | +| `cargo clippy --all -- -D warnings` | **0** | 11.5s | 0.39s | +| `cargo test --all` | **0** | 47.6s | 8.41s | +| `python3 scripts/check-worklog-json.py` | **0** | — | **0.04s** | +| **합계(3명령)** | | **60.2s** | **9.36s** | + +--- + +## 대가 (초 단위 — ★「0」이라고 쓰지 않았다) + +**잠금 단독 5회 실측**: `0.10 · 0.04 · 0.13 · 0.13 · 0.08` (초) ⇒ **중앙값 0.10s · 최대 0.13s**. + +★**비율은 «분모»에 달렸다 — 유리한 쪽만 적지 않는다**: +**재컴파일이 필요한 회차(60.2s) 기준 +0.17%** · ★**완전 캐시 회차(9.36s) 기준 +1.1%**. +⇒ **최악이 약 1%** 다. cold 빌드면 분모가 더 커져 비율은 더 내려간다. + +★**공짜가 아닌 축은 시간이 아니라 «사람이 기억해야 하는 줄»이다** — 제안 ⑵가 스스로 적은 대가다. +그 대가는 줄이지 못하고 **그대로 치렀다**(줄을 4개로 늘렸다). 대신 CLAUDE.md 한 줄 안에 묶어 +**읽는 단위는 1줄**로 유지했다. + +--- + +## 경계 준수 + +CI 워크플로 **무접촉**(새 워크플로 0 · `rust.yml` 변경 0) · 새 도구 **0** · 과거 회차 backfill **0** · +워크로그 «본문» 작성 요구 **0**(규약·잠금·결정만) · 코드(`.rs`) 변경 **0** · +머지 **0** · force-push **0** · 리베이스 **0** · `main` 직접 push **0** · base `main`(★스택 아님) · +upstream(`dlunch/RustJava`) 발신 **0** · 맨 `grep` **0**(문서에 넣은 스니펫도 `/usr/bin/grep`). + +★**고지 — 열린 PR #19 와 `REPORT.md`·`STATE.md` 상단이 겹친다.** 둘 다 그 두 파일 머리에 append 하므로 +**나중에 착지하는 쪽이 충돌**한다(내용 충돌 아님 · 인접 append). 게이트③이 순서를 정할 때 알고 있어야 한다. From 5702e78ae272a719f2449052c5708301b792fe5a Mon Sep 17 00:00:00 2001 From: jun0 Date: Fri, 4 Sep 2026 01:19:58 +0900 Subject: [PATCH 2/2] docs: record gate3 execution in the ledger [rustjava-worklog-mandate-decision-and-local-gate] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STATE.md 진행중 → 완료(게이트③ PR #20 · --merge 착지 · squash 금지 사유 명기) + worklog .json 에 게이트③ 집행 1줄. 코드 변경 0. --- STATE.md | 24 ++++++++++--------- ...-09-04-worklog-mandate-and-local-gate.json | 3 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/STATE.md b/STATE.md index 78b954cf..9d5fccc0 100644 --- a/STATE.md +++ b/STATE.md @@ -1,17 +1,6 @@ # STATE ## 진행중 -- [rustjava-worklog-mandate-decision-and-local-gate] ★**워크로그 작성을 DoD «의무»로 결정 + 형식 잠금을 - 로컬 DoD 4번째 명령으로 편입.** ★**코드 변경 0 · 새 도구 0 · CI 워크플로 무접촉.** - ★**먼저 쟀다**: 규약 착지(`b3a4cf4` · 2026-08-26) 이후 착지 **4회차 중 3건(75%)** 작성 · - 유일한 미작성(PR #13)은 **부모가 정확히 `b3a4cf4`** 라 규약을 알 수 없었다(알 수 있었던 회차만 **3/3**). - ★★**관측이 높은데도 의무화한 이유 = 실패가 «조용하고 잠글 수 없다»** — 잠금은 **존재하는 `.json` 만** - 검사하므로(비소급 설계) 아예 안 쓴 회차는 **red 0 · 카드만 0** 이다. 표본 3건 · 전건 같은 리니지. - ★**되돌릴 수**(`AGENTS.md` §Round Worklog · 측정 명령 동봉): **10회차 착지 시점** 재측정 — - ⒜미작성 ≥ 2 ⇒ 문안을 빼거나 **기계 강제로** ⒝열린 카드 < 5 ⇒ **의무 재검토**. - ★**`cargo test` 안으로 안 넣었다**: `serde_json` 이 `Cargo.lock` 에 **부재**(새 의존성 + 6셀 빌드) · - `python3` shell-out 은 python 없는 머신에서 **오탐 red** ⇒ 「오탐 0」 절대 조건 위반. - 대가 = **+0.10s**(3명령 warm 합계 60.2s 대비 **+0.17%**). **PR 대기 — 게이트③ 미착지.** - [rustjava-upstream-sync-remeasure-s5-s7-and-lock-restore-basis] ★**PR #18 착지 뒤 기준 S5~S7 재측정 + 「충돌 수에 base 병기」를 §5 상시 규칙으로 채택**(PR **#19** 대기). 같은 컷 `ba5797b` 가 **19 · 112 · 4** 로 갈린다 · 새 충돌 **S5 +3 · S6 +0 · S7 +1** · ★**S8 이 필요하다**(개명 스윕). @@ -37,6 +26,19 @@ (25번째 run, 앞선 24건 전부 red). **PR 대기 — 게이트③ 미착지.** ## 완료 +- [rustjava-worklog-mandate-decision-and-local-gate] ★**워크로그 작성을 DoD «의무»로 결정 + 형식 잠금을 + 로컬 DoD 4번째 명령으로 편입.** ★**코드 변경 0 · 새 도구 0 · CI 워크플로 무접촉.** + ★**먼저 쟀다**: 규약 착지(`b3a4cf4` · 2026-08-26) 이후 착지 **4회차 중 3건(75%)** 작성 · + 유일한 미작성(PR #13)은 **부모가 정확히 `b3a4cf4`** 라 규약을 알 수 없었다(알 수 있었던 회차만 **3/3**). + ★★**관측이 높은데도 의무화한 이유 = 실패가 «조용하고 잠글 수 없다»** — 잠금은 **존재하는 `.json` 만** + 검사하므로(비소급 설계) 아예 안 쓴 회차는 **red 0 · 카드만 0** 이다. 표본 3건 · 전건 같은 리니지. + ★**되돌릴 수**(`AGENTS.md` §Round Worklog · 측정 명령 동봉): **10회차 착지 시점** 재측정 — + ⒜미작성 ≥ 2 ⇒ 문안을 빼거나 **기계 강제로** ⒝열린 카드 < 5 ⇒ **의무 재검토**. + ★**`cargo test` 안으로 안 넣었다**: `serde_json` 이 `Cargo.lock` 에 **부재**(새 의존성 + 6셀 빌드) · + `python3` shell-out 은 python 없는 머신에서 **오탐 red** ⇒ 「오탐 0」 절대 조건 위반. + 대가 = **+0.10s**(3명령 warm 합계 60.2s 대비 **+0.17%** · 완전 캐시 회차 9.36s 대비 +1.1%). + ★게이트③ 완료: PR #20 — ★★**`--merge` 착지**(★`--squash` 아님. `rustjava` 는 `upstream-sync-repos.conf` + 등재 repo 라 스쿼시가 계보를 지운다 — #11·#13·#16·#17 이 그 형태였다). 머지커밋 sha 는 회신 `merged:` 참조. - [rustjava-upstream-sync-s3] upstream 컷 `822504b`(#180 오류 분류) 머지 — 충돌 **11** 해소. ★**S2(PR #13) 브랜치 «위에» 쌓았다** — 당시 `main` 에 S2 가 없어 base 를 `main` 으로 잡으면 S2 의 충돌 5건을 다시 만나기 때문이다. ★게이트③ 완료: PR #16 스쿼시 머지 → main **`4bb796d`**(2026-08-26). diff --git a/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json index f7bb9cca..7227f7bb 100644 --- a/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json +++ b/docs/worklog/2026-09-04-worklog-mandate-and-local-gate.json @@ -24,7 +24,8 @@ "★대가는 시간이 아니라 「사람이 기억해야 하는 줄」이다(제안 ⑵ 자신이 적은 대가). 그 대가는 줄이지 못하고 그대로 치렀다 — DoD 명령이 3 → 4 다.", "★열린 PR #19 와 REPORT.md·STATE.md 상단이 겹친다 — 둘 다 머리에 append 하므로 나중에 착지하는 쪽이 인접 충돌한다(내용 충돌 아님). 게이트③이 순서를 정할 때 알고 있어야 한다.", "CI 워크플로는 무접촉이다 — worklog_json job 은 그대로 두었다(로컬 편입은 CI 를 대체하지 않는다. CI 는 여전히 머지 전 그물이다).", - "머지하지 않았다 — 게이트②·③은 별 세션이다. upstream(dlunch/RustJava) 발신 0." + "머지하지 않았다 — 게이트②·③은 별 세션이다. upstream(dlunch/RustJava) 발신 0.", + "★[게이트③ 2026-09-04] PR #20 을 ★--merge 로 착지시켰다(★--squash 아님). rustjava 는 contracts/upstream-sync-repos.conf 등재 repo 라 스쿼시가 부모 2개를 1개로 접어 계보를 지운다 — #11·#13·#16·#17 이 그 형태로 merge-base 를 fork 시점에 묶어 두었다. 검수 핀 4a258215(불이동 확인) · 원장 동봉으로 head 가 한 번 움직였고 전/후 sha 는 회신에 있다." ], "proposals": [ {