이 노트에 대하여

이 노트는 “하네스 특화 투두 플랜을 거부한다”는 원칙에서 출발해, 변경 이력을 repo에 사는 텍스트(NEXT/CHANGELOG/ROADMAP/AGENTS)와 도구(commit/gitcli/tag-release)로 묶은 release 워크플로우 설계를 정리한다. nixos-config를 첫 CalVer dogfood로 삼아 실제로 돌려본 결과와, 그 과정에서 드러난 hook의 태그-push false positive까지 기록한다.

히스토리

  • [2026-05-31 Sun 18:06] 추가 — run.sh setup의 dirty-safe managed repo refresh + stale gitcli binary 방지 기록
  • [2026-05-31 Sun 17:48] 생성 — tag-release 스킬 설계 + nixos-config v2026.5.31 첫 dogfood 정리

출발점 — 하네스 투두 거부

여러 하네스(pi, Claude Code, OpenCode, Codex)를 오가면 각자의 TODO/플랜 시스템이 따로 논다. Claude Code의 TODO 기능은 꺼 두었고, pi는 날것이며, NEXT.md를 시작한 순간부터 복잡한 트래커를 안 쓴다.

결론은 하나다: 상태는 하네스가 아니라 repo에 사는 텍스트 파일에 둔다. 하네스가 바뀌어도 파일과 CLI는 그대로다. 이 노트의 워크플로우는 그 원칙의 구체화다.

문제 — 태그 0개가 changelog를 죽였다

nixos-config의 CHANGELOG.md는 [0.3.2] 2026-02-22 에서 3개월 멈춰 있었다. 게으름이 아니라 구조적 원인이었다.

  • update-changelog 스킬(아르민 원본)은 git describe --tags --abbrev=0 로 마지막 태그를 baseline 삼아 git log <tag>..HEAD 를 수집한다.
  • 그런데 nixos-config는 git 태그가 0개 였다. baseline 앵커가 없으니 자동화가 애초에 돌 수 없었다.

즉 도구는 있었지만 물고 들어갈 태그가 없었다. “워크플로우가 인지하지 못하는 문서는 생성 즉시 deprecated된다”의 전형.

설계 — 4문서 × 4도구, 두 루프

문서의 역할을 직교하게 가른다.

  • NEXT.md — 다음 할 일 (휘발성)
  • CHANGELOG.md무엇이 바뀌었나 (기계적, 태그 단위)
  • ROADMAP.md왜/어떻게 여기까지 왔나 (서사, 수기)
  • AGENTS.md — 현재 운영 상태 (영속 baseline)

도구는 두 개의 루프로 묶는다.

  • 일상 루프 (고빈도): 작업 → commit 스킬 → 커밋 후 agenda stamp → NEXT.md 갱신
  • 태그 루프 (저빈도): gitcli 로 지난 태그 이후 커밋 집계 → CHANGELOG 갱신 → CalVer 태그 컷(tag-release 스킬) → ROADMAP 스냅샷

CHANGELOG가 SSOT이고, GitHub 릴리즈 본문은 거기서 추출하는 render다.

결정들

  • update-changelogtag-release 로 rename하고 CalVer 태그 컷 절차를 흡수했다. 새 스킬은 0개 — 기존 스킬 확장.
  • commit 스킬은 살리되, AGENTS.md의 “Agenda Stamp on Git Commit” 절차(48줄 bash 블록)를 commit 스킬로 내렸다. 항상 로드되는 AGENTS.md는 436→397줄로 슬림화. commit 시점에만 로드되는 스킬이 지침을 전달한다.
  • 위험 비대칭 때문에 commit과 release를 한 스킬에 안 섞었다: commit은 고빈도·저위험·멱등(로컬), release는 저빈도·고위험·외부 발행(push/tag, 되돌리기 어려움).
  • SemVer를 폐기하고 CalVer 를 채택했다. 인프라 /config repo는 major/minor/patch 의미가 약하다 — NixOS 자체가 CalVer다. 태그 형식은 OpenClaw 생태계와 맞춰 vYYYY.M.D (선택적 -beta.N=/-rc.N=).
  • CalVer의 함정 하나: zero-pad가 없는 vYYYY.M.D 는 plain 문자열 정렬이 시간순과 어긋난다(v2026.5.9 > v2026.5.31). version-aware 정렬(git describe, --sort=version:refname)만 쓰고 plain sort 를 금하는 가드를 스킬에 박았다.

gitcli 실버그 수정

태그 루프가 gitcli log <repo> --from <date> 로 재료를 모으는데, 실제로 돌려보니 --from 단독으로는 동작하지 않고 기본 7일로 떨어졌다(--to 없으면 무시). CalVer 태그 날짜 파싱(v2026.5.30-beta.12026-05-30)도 함께 추가했다. 설계가 도구의 숨은 버그를 드러낸 자리.

첫 dogfood — nixos-config v2026.5.31

  • CHANGELOG를 CalVer로 전환. ## v2026.5.31 첫 스냅샷에 3개월(213커밋)을 Added/Changed/Fixed로 압축하고, OpenClaw 버전 hop 디테일은 ROADMAP 참조로 위임. 기존 SemVer 0.1.0~0.3.2 라인은 역사로 보존.
  • ROADMAP “현재 위치”를 v2026.5.31 스냅샷으로: 4 디바이스(oracle/nuc/laptop/thinkpad) + Docker 10 스택 = “oracle를 통째로 재현하는 공개 인프라”라는 정체성을 전면에.
  • NEXT에 26.05 업그레이드 항목(25.11 EOL 2026-06-30).

발견 — 태그 push hook false positive

git push origin v2026.5.31 이 글로벌 안전 hook에 막혔다. 사유는 machines/gpu-03.nix 의 식별어인데, 이 파일은 이미 origin/main에 있는 grandfathered 내용이고 태그가 가리키는 커밋도 이미 push된 68a0baf 였다. 태그가 새로 도입하는 변경은 0줄이어야 정상.

원인은 태그-push 시 hook이 remote-reachable 커밋을 baseline에서 빼지 못하고 넓은 범위를 added로 재스캔하는 것. AGENT_ALLOW_UNSAFE_COMMIT 은 정책상 에이전트가 쓰지 않으므로 STOP하고 GLG에게 보고했다. 도구 underperformance는 도구 이슈로 기록한다는 원칙의 사례.

멀티 하네스 SSOT

이 모든 변경은 nixos-config 한 곳이 아니라 agent-config 에 산다. run.sh setup 이 skills 디렉토리를 스캔해 pi / Claude plugin / Codex / OpenCode 등 모든 하네스로 심볼릭 링크한다. 한 곳을 고치면 전 하네스에 퍼진다 — 그래서 “여기만 잘하면 소용없다”가 아니라 “여기를 고치면 전부 고쳐진다”.

관련 노트

  • nixos-config ROADMAP.md / CHANGELOG.md (repo 내, v2026.5.31)
  • agent-config skills/tag-release/ / skills/commit/ (워크플로우 SSOT)

[2026-05-31 Sun] setup freshness — stale binary를 빌드하지 않기

이번 루프의 마지막 퍼즐은 run.sh setup 이었다. 기존 철학은 “setup은 pull하지 않는다”였고, 이는 작업 중인 외부 repo를 건드리지 않기 위한 안전장치였다. 하지만 그 결과 Oracle/다른 장비에서 gitcli repo가 stale이면, setupstale source를 그대로 다시 빌드 하는 문제가 생겼다. GLG가 매번 “먼저 update”를 기억해야 한다면 워크플로우 실패다.

정리한 원칙:

  • dirty repo는 절대 pull하지 않는다 — 수정 중인 작업은 보호한다.
  • clean한 managed build input은 setup이 fast-forward refresh한다 — 업데이트된 것은 가져와서 빌드한다.
  • opt-out은 AGENT_CONFIG_SETUP_NO_UPDATE=1 ./run.sh setup.

구현: agent-config/run.shsetup 앞단에 self-refresh와 managed repo refresh를 추가했다. agent-config 자신이 clean + behind이면 git pull --ff-only 후 새 run.shexec 재시작한다. gitcli/denotecli/lifetract/dictcli/zotero-config 같은 managed repo는 clean일 때만 fetch+fast-forward하고, dirty/diverged/no-upstream이면 warning 후 local source로 build한다.

검증: ./run.sh setup 에서 gitcli: up to date 후 build, Binaries: 6/6, gitcli --version => 0.3.0. 커밋 4a9b5d4 chore(setup): refresh clean managed repos 로 agent-config에 반영하고 push/stamp 완료.

이 결정은 “setup이 작업 중인 repo를 건드리지 않는다”는 기존 철학의 폐기가 아니라, 그 핵심을 더 정확히 구현한 것이다. 보호 대상은 dirty worktree이고, stale dependency는 보호 대상이 아니다.