From c5277a24c01a59aeb009d81c67aa8007b6a2f820 Mon Sep 17 00:00:00 2001 From: jun0 Date: Fri, 25 Sep 2026 01:56:19 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[rustjava-report-state-md-per-round-files-p?= =?UTF-8?q?ort-from-wie]=20docs(ledger):=20REPORT.md=C2=B7STATE.md=20?= =?UTF-8?q?=EB=8F=99=EA=B2=B0=20=E2=80=94=20=ED=9A=8C=EC=B0=A8=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=EC=9D=80=20docs/worklog/=20=ED=9A=8C=EC=B0=A8?= =?UTF-8?q?=EB=B3=84=20=ED=8C=8C=EC=9D=BC=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 모든 PR 이 두 공유 원장 앞에 덧붙여 착지 1회가 열린 형제 PR 전건을 충돌시켰다 (2026-09-10~25 PR 61 중 합집합 머지 42). 두 파일은 보존하고 해시로 고정한다 (scripts/check-ledgers-frozen.py · CI worklog_json + 로컬 DoD). 다음 = docs/next.md. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/rust.yml | 1 + AGENTS.md | 24 +++++++++++++++++++++ CLAUDE.md | 12 ++++++----- REPORT.md | 1 + STATE.md | 1 + docs/next.md | 25 ++++++++++++++++++++++ scripts/check-ledgers-frozen.py | 37 +++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 docs/next.md create mode 100755 scripts/check-ledgers-frozen.py diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d7701949..befc1337 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -61,6 +61,7 @@ jobs: steps: - uses: actions/checkout@v7 - run: python3 scripts/check-worklog-json.py + - run: python3 scripts/check-ledgers-frozen.py # a conflict resolution that drops one side's work leaves no other trace: no marker, mergeable # CLEAN, suite green. fetch-depth 0 because the check needs the merge commits and their parents, diff --git a/AGENTS.md b/AGENTS.md index 4e6a24ba..80b192b5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,30 @@ basename** in `docs/worklog/`: `YYYY-MM-DD-.md` (the human axis) and `YYYY-MM-DD-.json` (the machine axis). Without the `.json`, the proposal is **structurally unreachable** by the cockpit "후속 작업 추천" panel — its scanner reads `.json` only. +**Since 2026-09-25 the `.md` is written by every round, and it is the round record.** `REPORT.md` +and `STATE.md` are frozen (ticket `rustjava-report-state-md-per-round-files-port-from-wie`, ported +from wie `a5091df6`). Every PR used to add to the top of those two shared files, so each landing +made every open sibling conflict: **42 union merges out of 61 PRs** from 2026-09-10 to 2026-09-25. +A file named after its own round has no shared line to fight over. So: + +- **Every round** creates `docs/worklog/YYYY-MM-DD-.md`. Its first line is + `## [YYYY-MM-DD] title ()`, followed by the 무엇을·왜·사용자 영향 lines that used to go + into `REPORT.md`. Add the `.json` sibling when the round leaves proposals or disposes of them, + as below. +- **진행중** is `gh pr list -R Jun025/RustJava`. **완료** is this directory: + `grep -H '^## \[' docs/worklog/*.md | sort -r`. **다음** is `docs/next.md`, and a round edits it + only when a prerequisite chain or an item outside the cards changes. Adopting or declining a + card is recorded in the round's own `.json`, which is not a shared file. +- `scripts/check-ledgers-frozen.py` pins both frozen files by hash. It runs in the `worklog_json` + CI job and in the local DoD, and any edit to either file turns it red. If a merge conflict + offers you one of those files, take `main`'s side and move your entry into your own `.md`. +- Names are `date-slug`, not wie's serial `NNNN--`. The slug is the round's own name, so two open + PRs never pick the same filename. That also means this repo does not need wie's + serial-collision checker. + +Text below that says "into `REPORT.md`" means the round's `.md` from 2026-09-25 on. It is kept +as written because it records decisions that were made at the time. + **Do not invent a schema** — these key names are shared with otterpebble/dodu/qts. The consumer (`/api/proposals`, `scanRepoSimple`) reads exactly these: diff --git a/CLAUDE.md b/CLAUDE.md index 2effba1a..d2a86899 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,6 +30,7 @@ cargo clippy --workspace --exclude test-utils --target wasm32-unknown-unknown -- -D warnings cargo test --all python3 scripts/check-worklog-json.py + python3 scripts/check-ledgers-frozen.py python3 scripts/check-dod-ci-parity.py python3 scripts/check-named-exception-classes-are-loadable.py python3 scripts/check-merge-dropped-symbols.py @@ -53,10 +54,11 @@ `test-utils` 로 개명(S8)했을 때 **로컬에서는 어떤 명령으로도 드러나지 않고 CI 에서만** 빨개졌다. ⇒ ★**CI 가 검사를 늘리거나 «매트릭스 차원»을 바꾸면 이 블록도 «같이» 고쳐라**(아래 재개 조건이 둘 다 센다). ※OS 축(3종)은 로컬에서 재현할 수 없다 — ★**그 차원만은 CI 가 유일한 그물이고, 그것은 «알고 두는» 값이다.** -- 착수·완료마다 STATE.md 의 "진행중/완료/다음" 을 갱신하고, 완료 시 REPORT.md 상단에 - `[YYYY-MM-DD]` 요약 3줄(무엇을·왜·사용자 영향) + 후속 추천을 append 한다. -- ★**후속 추천을 적었으면 `docs/worklog/YYYY-MM-DD-.{md,json}` 한 쌍도 남긴다** — - `.json` 이 없으면 그 추천은 cockpit 「후속 작업 추천」 패널에 **구조적으로 도달하지 못한다** - (규약·되돌릴 수 = `AGENTS.md` §Round Worklog). +- ★**회차 기록은 회차마다 새 파일 `docs/worklog/YYYY-MM-DD-.md` 에 쓴다.** 첫 줄에 + `## [YYYY-MM-DD] 제목 ()`, 그 아래 무엇을·왜·사용자 영향 3줄을 적는다. 후속 추천을 적었으면 + 같은 basename 의 `.json` 도 쓴다. `.json` 이 없으면 그 추천은 cockpit 「후속 작업 추천」 패널에 **닿지 못한다**. + ★**`REPORT.md`·`STATE.md` 는 2026-09-25 에 동결됐다 — 건드리지 마라**(`scripts/check-ledgers-frozen.py` 가 red 를 낸다). + 진행중 = `gh pr list -R Jun025/RustJava` · 완료 = `docs/worklog/` · 다음 = `docs/next.md` + (규약 = `AGENTS.md` §Round Worklog). - ★작업 티켓의 **완주 지점 = PR 오픈**이다. 머지는 게이트② 검수자가 approve 와 같은 턴에 집행한다(`-merge` 는 예외 경로) (`main` 직push 0 — `AGENTS.md` §Git Workflow). diff --git a/REPORT.md b/REPORT.md index 33621c90..2b7c9c28 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,4 +1,5 @@ # REPORT +> ★**동결 — 2026-09-25 이후 기록은 `docs/worklog/YYYY-MM-DD-.md`(회차마다 새 파일) · 다음 = `docs/next.md` · 진행중 = `gh pr list -R Jun025/RustJava`.** 이 파일을 고치면 `scripts/check-ledgers-frozen.py` 가 red 를 낸다(규약 `AGENTS.md` §Round Worklog). ## [2026-09-24] «파일 끝에 남는 바이트» 거부가 클래스가 끝난 위치를 말한다 (rustjava-2026-09-23-validation-rules-name-their-position-adopt-p0) - 무엇을: parse-level 거부 3종을 재어, 정확한 위치를 쥔 «extra bytes» 하나만 `Location::ByteOffset` 으로 오프셋을 싣는다. «truncated or unparsable» 은 nom 오프셋이 손상 지점을 절반 가까이 빗나가 두었고, «version < 45.0» 은 가리킬 자리가 없다. - 왜: 채택 제안 `2026-09-23-validation-rules-name-their-position#p0`. 제안의 예상(«truncated» 가 후보, 나머지는 없음)은 측정으로 뒤집혔다. diff --git a/STATE.md b/STATE.md index 4fe092b7..7a2c0bb8 100644 --- a/STATE.md +++ b/STATE.md @@ -1,4 +1,5 @@ # STATE +> ★**동결 — 2026-09-25 이후 기록은 `docs/worklog/YYYY-MM-DD-.md`(회차마다 새 파일) · 다음 = `docs/next.md` · 진행중 = `gh pr list -R Jun025/RustJava`.** 이 파일을 고치면 `scripts/check-ledgers-frozen.py` 가 red 를 낸다(규약 `AGENTS.md` §Round Worklog). ## 진행중 (없음 — 2026-09-17 실측: 착수 시 열린 PR **4건**(#56·#57·#58·#59). ★**내 경로와 겹치는 것은 둘**이다 — diff --git a/docs/next.md b/docs/next.md new file mode 100644 index 00000000..08e76b46 --- /dev/null +++ b/docs/next.md @@ -0,0 +1,25 @@ +# 다음 + +`STATE.md` `## 다음` 을 옮긴 것이다(2026-09-25 · `rustjava-report-state-md-per-round-files-port-from-wie`). +그 뒤로 `STATE.md` 는 동결됐다. 규칙은 `AGENTS.md` §Round Worklog 에 있다. + +★**이 파일에는 카드가 표현하지 못하는 것만 적는다**: 선행 사슬과 카드 밖 항목(PR 번호). 열린 카드 목록은 적지 마라 — 아래 명령으로 세라. +옮기기 전 `STATE.md` 의 「순서 없음」 4줄 중 2줄은 이미 닫혀 있었다(`…bootstrap-argument-index-and-tag#p0`·`…unraisable-error-variant#p0`). +직접 적어 둔 목록은 이렇게 낡는다. + +```sh +# 열린 카드 = proposals − adopted − declined (tower 의 «− injected» 술어가 아니다) +python3 -c " +import json,glob,os +refs=[];done=set() +for f in sorted(glob.glob('docs/worklog/*.json')): + d=json.load(open(f));b=os.path.basename(f)[:-5] + refs+=[f'{b}#p{i}' for i in range(len(d.get('proposals',[])))] + done|=set(d.get('adoptedProposals',[]))|set(d.get('declinedProposals',[])) +print(*[r for r in refs if r not in done],sep='\n')" +``` + +1. **선행 사슬**: `2026-09-17-link-lambdametafactory#p1`(결정) → `#p0`(어댑터) → `java.lang.invoke` 패키지(카드 없음 · 근거 = `rustjava-runtime/src/classes/java/lang/invoke` **부재**) → `2026-09-17-string-concat-recipe-arity#p1`. +2. **카드 밖**: PR **#81**. 2026-09-23 에 `CONFLICTING` 이었고 충돌 해소가 먼저다. + +지난 판(⓪-사료·①~⑤)은 동결된 `STATE.md` `## 다음` 아래에 그대로 있다. diff --git a/scripts/check-ledgers-frozen.py b/scripts/check-ledgers-frozen.py new file mode 100755 index 00000000..2609984e --- /dev/null +++ b/scripts/check-ledgers-frozen.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +"""Refuse any change to the frozen ledgers `REPORT.md` and `STATE.md`. + +Why: until 2026-09-25 every PR prepended to these two files. Each landing then conflicted with +every open sibling PR: 42 union merges out of 61 PRs between 2026-09-10 and 2026-09-25. Round +records now go to per-round files in `docs/worklog/` (AGENTS.md §Round Worklog), and the two files +are kept as history. A round that goes back to the old habit would bring the conflicts back, so +the files are pinned by hash here. + +A merge conflict in either file means your side added an entry. Take `main`'s side and move the +entry into your round's `docs/worklog/*.md`. +""" + +import hashlib +import sys +from pathlib import Path + +FROZEN = { + "REPORT.md": "dd2f16f4e0da590919fcfcdb71d4f9ad6105d1c58b8284472fdaff1b0dab9079", + "STATE.md": "38a53e3c415a609b265334e69a59cfd4b31cc4ad4a284b567d9377c47f5b6e02", +} + +root = Path(__file__).resolve().parent.parent +bad = [] +for name, want in FROZEN.items(): + path = root / name + got = hashlib.sha256(path.read_bytes()).hexdigest() if path.exists() else "missing" + if got != want: + bad.append(f"{name}: sha256 {got} != frozen {want}") + +if bad: + print("check-ledgers-frozen: FAIL — these files are frozen since 2026-09-25", file=sys.stderr) + for line in bad: + print(f" {line}", file=sys.stderr) + print(" write the round entry to docs/worklog/YYYY-MM-DD-.md instead (AGENTS.md §Round Worklog)", file=sys.stderr) + sys.exit(1) +print(f"check-ledgers-frozen: ok — {len(FROZEN)} frozen ledgers unchanged") From 285f09feb44490345cf991055b596c1a63897250 Mon Sep 17 00:00:00 2001 From: jun0 Date: Fri, 25 Sep 2026 01:56:19 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[rustjava-report-state-md-per-round-files-p?= =?UTF-8?q?ort-from-wie]=20docs(worklog):=20=EC=9D=B4=20=ED=9A=8C=EC=B0=A8?= =?UTF-8?q?=20=EA=B8=B0=EB=A1=9D=20=E2=80=94=20=EC=83=88=20=EA=B7=9C?= =?UTF-8?q?=EC=B9=99=EB=8C=80=EB=A1=9C=20=ED=9A=8C=EC=B0=A8=EB=B3=84=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=ED=95=98=EB=82=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/worklog/2026-09-25-ledgers-frozen-per-round-files.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs/worklog/2026-09-25-ledgers-frozen-per-round-files.md diff --git a/docs/worklog/2026-09-25-ledgers-frozen-per-round-files.md b/docs/worklog/2026-09-25-ledgers-frozen-per-round-files.md new file mode 100644 index 00000000..759cfbbf --- /dev/null +++ b/docs/worklog/2026-09-25-ledgers-frozen-per-round-files.md @@ -0,0 +1,6 @@ +## [2026-09-25] `REPORT.md`·`STATE.md` 동결 — 회차 기록은 회차별 파일로 (rustjava-report-state-md-per-round-files-port-from-wie) +- 무엇을: 두 원장 머리에 동결 1줄을 달고 해시로 고정했다(`scripts/check-ledgers-frozen.py` · CI `worklog_json` job + 로컬 DoD). 회차 기록은 `docs/worklog/YYYY-MM-DD-.md`, 진행중은 `gh pr list`, 다음은 `docs/next.md` 로 옮겼다. +- 왜: 모든 PR 이 두 파일 맨 앞에 덧붙여서 착지 1회가 열린 형제 PR 전건을 충돌시켰다. 2026-09-10~25 PR 61건에 합집합 머지가 42건이었다(`origin/main` 실측). wie `a5091df6` 선례를 포팅했다. +- 사용자 영향: 없음(문서·검사). 회차 PR 이 공유 줄을 만지지 않으니 원장 충돌 재회차가 사라진다. ★열린 PR #81 은 두 원장을 만진다 — 착지 전에 그 항목을 자기 worklog `.md` 로 옮겨야 한다. + +wie 와 다른 점: 새 `docs/report/NNNN--` 연번 디렉터리 대신 기존 `docs/worklog/` 의 `date-slug` 이름을 쓴다(파일 이름이 겹치지 않으니 연번 충돌 검사기가 필요 없다). `STATE.md` 도 한 번에 전부 동결했다(wie 는 진행중·완료를 두 번에 걸쳐 포인터로 바꿨다). 과거 기록은 옮기지 않았다.