[AKM] 업데이트는 계속 받으면서, 내 규칙은 따로 얹기

배경 — 왜 이 작업이 필요했나

AKM은 이미 효과를 봤습니다

DECK님이 만든 오픈소스 지식관리 프레임워크 AKM을 클론해서 이틀 돌려본 기록입니다. DB도 서버도 안 쓰고 마크다운 파일과 규칙만으로 굴러갑니다. 저장 공간은 7개 계층으로 나뉘고, 새 정보가 어디로 갈지는 라우터가 정하며, 수집부터 검증과 학습 환원까지 7단계 루프가 돕니다.

2주 쌓았더니 신규 조사 0건으로 시장 브리핑과 전략 검증 보고서가 나왔습니다. 볼트가 찾아보는 폴더에서 믿고 쓰는 베이스로 바뀐 셈이죠.

그런데 벽이 두 개 있었습니다

벽 ① — 개념이 어렵다.

7계층, 라우터, 4가지 분류 원칙, 검증 티어, akmLayer·akmType·akmRole… 솔직히 저도 매번 문서를 다시 열어봅니다. 이걸 다 알아야 파일 하나 넣을 수 있나 싶었어요. 함께 일하는 동료들과 같이 쓰고 싶은데, 지금 상태로 "이거 좋으니까 같이 쓰자"고 하기엔 조금 망설여집니다.

벽 ② — 코어를 내 맘대로 고칠 수 없다.

개인-업무-팀단위의 지식관리 파이프라인을 염두하고 잡다 보니 관리 항목이 자꾸 생겼습니다. 표준 파일을 고치면 간단히 해결되는데, 여기서 걸렸어요.

제 저장소는 DECK6/akm을 복제해 만든 것입니다. 표준파일( SCHEMA.md·ROUTER.md 같은 규칙 문서와 린터, 템플릿)을 제 마음대로 고치면, 지속적으로 업데이트 되는 버전을 받을때마다 충돌이 발생할거에요.

upstream이 그 파일을 고침   +   내가 그 파일을 고침
        └────────  받을 때마다 충돌  ────────┘

목표 — 3단 지식관리 파이프라인 구축

제가 만들려는 건 이 구조입니다.

개인 볼트          →     업무 볼트          →      팀 볼트
개인 관심사·동향       개인의 회사 공식 업무        진행/완료된 팀공식 문서

각 단계 사이에는 승격 게이트를 둡니다. 개인 메모가 검증도 없이 팀 문서가 되면 곤란하니까요.

이걸 만들려면 두 벽을 다 넘어야 합니다. 사람이 붙을 수 있어야 하고(벽 ①), 내 필요를 채우면서도 upstream을 계속 받을 수 있어야 하죠(벽 ②). 오늘 붙잡은 게 이 둘입니다.


0. 먼저 — 상태 필드 세 개가 뭔가

뒤 이야기를 따라가려면 이것부터 알아야 합니다. AKM은 모든 노트 맨 위에 메타데이터를 다는데, 그중 상태를 나타내는 게 세 개예요.

trustLevel — 이 노트를 얼마나 믿어도 되나 (필수)

읽는 사람이 판단할 정보입니다.

raw

원본 그대로, 해석 안 붙임

draft

작업 중, 아직 아무도 안 봄

unverified

정리는 끝났고 확인은 안 함 ← 제일 위험한 구간

reviewed

사람이 봤거나 절차상 검증 통과

canonical

이 주제의 기준 문서

deprecated

수명 끝, 치울 후보

nextAction — 다음에 뭘 해야 하나 (선택)

쓰는 사람을 위한 할 일 표시입니다. trustLevel이 상태라면 이건 동사예요.

다음에 할 일

triage

인박스에서 분류 대기

classify

어느 계층으로 갈지 판정

merge

다른 자료와 합쳐 지식으로

contextualize

내 프로젝트에 붙이기

develop-into-skill

절차·스킬로 승격

verify

검증 필요

publish

밖으로 내보내기

archive

보관

enforce

규칙으로 강제

CMDS — 이 노트가 생애주기 어디쯤인가 (선택)

Connect(수집) → Merge(지식화) → Develop(절차화) → Share(산출).

헷갈리기 쉬운 점이 하나 있습니다. 이건 진행도 표시가 아닙니다. 이 노트가 무엇인지를 나타내요. 그래서 소스 노트는 지식화가 끝난 뒤에도 계속 Connect예요. 원본은 여전히 원본이니까요. 지식화의 결과는 새로 생긴 지식 노트가 Merge를 달고 나타나는 것으로 표현됩니다.


1. 벽 ①에 대한 답 — 사람이 읽을 정보를 모아주자

AKM의 7계층 폴더는 에이전트가 새 정보를 어디 넣을지 판단하려고 만든 구조지, 사람이 아침에 열어보라고 만든 게 아닙니다. 개념이 어렵게 느껴질 수밖에요.

그래서 방향을 바꿨습니다.

폴더는 에이전트의 라우팅 구조로 그냥 두고, 사람은 뷰(대시보드)로 들어온다.

만든 건 두 개입니다.

  • 00_지금 — 사람용 진입 노트. "지금 뭘 해야 하나"로 시작합니다

  • Bases 뷰 4개 — 상태를 보는 운영 뷰 3개(할일 / 수집함 / 검증대기), 그리고 주제별로 묶어둔 편의 뷰 하나(경쟁사)

이제 동료에게 "이 노트 하나만 열어보세요"라고 말하면 됩니다.

그런데 뷰는 무엇으로 만드나 — 여기서 상태 필드가 나옵니다

운영 뷰 셋은 위에서 설명한 세 필드를 질의합니다. 할일 뷰는 nextAction이 있는 노트를 모으고, 검증대기 뷰는 trustLeveldraft·unverified·raw인 것을 잡습니다. 수집함 뷰는 소스 전체를 nextAction 값별로 묶고요.

경쟁사 뷰만 성격이 다릅니다. 태그로 걸러서 관련 지식을 한자리에 모아둔 것이고, 제 편의를 위한 예시예요. 이런 건 필요할 때마다 하나씩 붙이면 됩니다. 절차 계층에 스킬을 하나 추가하는 것과 같아요. 고정 구성은 앞의 셋이고, 나머지는 확장 슬롯인 셈입니다.

건수는 손으로 적지 않습니다. 손으로 유지하는 숫자는 곧 거짓말이 되니까 항상 뷰를 열어서 봅니다.

여기서 짚어둘 게 있습니다. 새 규칙을 만든 게 아닙니다.

예를 들어 "검증이 안 끝났는데 다음 행동도 없으면 방치"는 원래부터 참이었어요. 코어 LOOP.md가 *"unverified로 둘 때는 nextAction: verify를 함께 단다"*고 지시하고 있으니, 빈칸이면 그 지시를 안 따른 겁니다. 다만 그걸 확인하려면 노트를 하나씩 열어봐야 했죠.

뷰가 한 일은 이미 있던 규칙을 조회 가능하게 만든 것이 전부입니다. 벽 ①의 답이 "규칙을 더 만들자"가 아니라 "있는 규칙을 보이게 하자"였던 이유예요.

그런데 뷰를 만들다 보니 상태 필드 쪽에서 손볼 게 자꾸 나왔습니다. 그게 벽 ②로 이어졌어요.

1-1. 만들면서 밟은 지뢰 — 뷰가 조용히 부풀었습니다

검증대기 뷰가 14건을 띄웠습니다. "미검증 노트가 14건이나 있다"로 읽히는 숫자죠.

실제로는 2건이었습니다. 나머지 12건은 저장소에 딸려온 템플릿과 예시 파일이었어요.

원인이 셋이었고 전부 재현됐습니다.

증상

원인

groupBy: akmType이 안 먹음

문자열이 아니라 객체여야 함

nextAction != ""이 값 없는 노트까지 통과

값이 아예 없으면 != 조건을 만족해버림

not: [inFolder(...)]가 제외를 못 함

not: 자체가 작동하지 않음

무서운 건 행이 늘어나는 오류라는 점입니다. 줄어들었다면 바로 눈치챘을 텐데, 늘어나면 그냥 발견처럼 보이거든요.

재발 방지는 원리로 정했습니다. 빼기(!=, not:) 대신 더하기로 고르기로 한 건데, 원하는 값을 ==로 나열하면 값이 없는 노트는 어떤 조건에도 안 걸립니다. 통과 자체가 원리적으로 불가능해지는 거죠.


2. 벽 ②에 대한 답 — 표준 파일 옆에 내 파일을 둔다

작업하면서 필요한 게 여럿 생겼습니다. 새 폴더도 필요했고, 새 필드도 필요했고, upstream이 정의를 안 해둔 값의 뜻도 정해야 했어요. 전부 표준 파일을 고치면 끝나는 일이고, 전부 그러면 안 되는 일이었습니다.

원리는 하나로 정리됐습니다.

upstream 파일을 고치지 말고, 그 옆에 내 파일을 둔다.

이걸 네 군데에 적용했습니다. 무엇이 어느 표준과 짝인지 먼저 펼쳐두면 이렇습니다.

종류

내가 더한 것

짝이 되는 upstream 표준

내 파일

폴더

30-context/standing/ — 끝나지 않는 일의 자리

SCHEMA.md 계층 정의 · ROUTER.md Q4

SCHEMA.local.md §1·§5 · ROUTER.local.md Q4

필드

intakeReason — 왜 이걸 넣었나

SCHEMA.md 필드 목록

SCHEMA.local.md §2

필드

archiveReason·resumeBy — 보류인가 폐기인가

SCHEMA.md 필드 목록 · ROUTER.md Q8

SCHEMA.local.md §2·§3 · ROUTER.local.md Q8

필드

pulledVersion·lastPulledAt — 외부 위키를 다시 당길지 판정

SCHEMA.md 필드 목록

SCHEMA.local.md §2

정의

nextAction 값 9개가 각각 무슨 작업인지

SCHEMA.md — enum만 나열돼 있음

SCHEMA.local.md §4

분류

아직 소화 안 된 생각은 어디로 보낼까

ROUTER.md Q6

ROUTER.local.md Q6

형식

standing/ 원장 · 발행 대장

upstream에 없음

SCHEMA.local.md §5·§6

파일

내 작업 기록을 코어 기록과 분리

LOG.md

LOG.local.md

절차

근거 상태 태깅

표준 문서가 아님

50-procedures/skills/tag-evidence-status.md

마지막 줄이 눈에 띌 텐데, 뒤에서 설명합니다.

① 규칙을 넓힐 때 → .local 확장 문서

가장 크게 쓴 방법입니다. upstream 규칙 문서 옆에 같은 이름의 확장 문서를 두고, 둘을 항상 함께 읽습니다.

upstream (무수정)

내 확장

99-system/SCHEMA.md

SCHEMA.local.md (198줄)

99-system/ROUTER.md

ROUTER.local.md (84줄)

작동하게 만드는 장치가 둘 있습니다.

우선순위 규칙. 확장 문서 머리에 이렇게 못 박았습니다.

upstream 파일과 충돌하면 upstream이 이긴다. 여기서는 upstream이 정하지 않은 것만 정한다.

덕분에 나중에 upstream이 같은 걸 정하면 제 확장이 알아서 물러납니다. 다툴 일이 없어요.

세션 포인터. 40-memory/local-extensions.md에 "규약을 볼 때 둘을 함께 읽어라"를 적어뒀습니다. 이 폴더는 매 세션 먼저 로드되는 자리라, 에이전트가 규칙을 참조할 때 확장을 빠뜨리지 않습니다.

위 표의 폴더·필드·정의·형식이 전부 이 두 파일에 들어 있습니다. 몇 가지만 짚으면 —

standing/은 upstream에 자리가 없던 것입니다. upstream 30-context/users·projects·domains·constraints 넷인데, 정례회의나 지표관리처럼 끝나지 않는 일을 둘 데가 없었어요. 판정 질문은 하나입니다. 완료 판정이 있는가? 있으면 projects/, 없으면 standing/.

intakeReasondescription과 다릅니다. description이 내용 요약이라면 이건 내 의도예요 — "왜 이걸 넣었나". 없으면 착지 후 되묻습니다.

nextAction 정의는 채워 넣은 쪽입니다. upstream이 값 9개를 나열만 하고 각각이 무슨 작업인지 안 적어놨거든요. 그래서 값마다 정의와 근거를 달았는데, 여기서 판단이 하나 갈렸습니다. 9개 중 publishenforce안 쓰기로 했어요. upstream 테스트 픽스처를 보니 출처가 이렇게 적혀 있더군요.

description: "Fixture covering enum values promoted from the production AKM instance."
nextAction: enforce

다른 운영 인스턴스에서 쓰던 값이 enum으로 올라왔고, 그 사용례는 딸려오지 않은 것입니다. 설계에서 나온 값이 아니니 제 쪽에서 억지로 의미를 만들지 않았습니다.

② 기록이 섞일 때 → 파일을 갈라 담는다

필요: 내 작업 기록이 코어 시스템 기록과 섞이지 않게 하고 싶다.

코어의 LOG.md에 제 기록을 계속 쌓으면 upstream 업데이트와 정면으로 부딪힙니다. 그래서 갈랐어요.

파일

담는 것

upstream과

LOG.md

코어 시스템 변경 이력

공유

LOG.local.md

내 인스턴스 작업 기록

안 섞임

원래 INDEX.md / INDEX.local.md가 쓰던 규약을 로그에도 적용한 겁니다.

효과는 그날 바로 확인됐습니다. v0.3을 받을 때 upstream도 LOG.md에 줄을 추가했는데, 제 기록은 이미 다른 파일로 빠져 있어서 충돌 없이 병합됐어요.

③ 스키마에 안 맞을 때 → 본문에 적는다

필요: 인용한 주장마다 "원문을 직접 봤나, 검색만 했나"를 표시하고 싶다.

이건 문장 단위입니다. 노트 하나에 주장이 수십 개니 프런트매터에 담을 수가 없어요. 그릇 자체가 없는 셈이라 .local 확장으로도 해결이 안 됩니다.

그래서 이것만 짝이 되는 표준 문서가 없습니다. 형식(SCHEMA)도 분류(ROUTER)도 아니고, "언제 무슨 작업을 하는가"라서요. 자리는 50-procedures/skills/tag-evidence-status.md절차 계층의 스킬 노트입니다. 규칙을 넓히는 게 아니라 작업 방법을 하나 추가한 거예요.

5단계로 정했습니다.

상태

Candidate

검색으로 찾았고 원문은 안 봄 → 이대로는 결과물에 못 씀

Direct Read

그 문서를 실제로 열어 읽음

Claim Supported

읽어보니 내 주장을 실제로 뒷받침함

Conflicted

다른 자료와 충돌

Stale

맞긴 한데 철 지남

핵심은 Direct ReadClaim Supported를 굳이 나눈 겁니다. 읽었다는 것과, 읽었더니 내 말이 맞더라는 건 다르니까요.

그래서 본문에 인라인 한 줄로 적습니다.

… 국내 시장 규모는 43조원으로 추정된다.
Evidence: Direct Read

5회 시범 사용 후 통과 판정을 냈는데, 그때도 스키마 필드로 승격할지는 따로 결정한다며 코어를 안 건드렸습니다. 실제로 4회차에서는 잘못된 통계 하나가 결과물에 들어가는 걸 막았고요. 단위가 다른 두 숫자를 나눈 계산이었는데, 정작 각 숫자는 원문에서 직접 확인한 것이었습니다.

배운 것. 같은 것을 재는 숫자가 아니면 각각이 아무리 정확해도 나누는 것 자체가 무효다.

④ 보류와 폐기를 구분하고 싶을 때 → 별도 필드로 갈라준다

upstream은 아카이브로 보낼 때 trustLevel: deprecated만 요구합니다. 그런데 거기 들어가는 것에는 두 종류가 있어요.

  • 종료 게이트를 안 타고 잠깐 멈춘 것 — 자산이 아직 폴더 안에 있습니다

  • 폐기했거나 종료를 마친 것 — 남은 건 껍데기입니다

인용해도 되는지가 갈리는데 필드로는 구분이 안 됐습니다. 둘 다 deprecated니까요.

그래서 archiveReason을 더했습니다. upstream이 요구하는 trustLevel: deprecated는 그대로 지키면서요.

archiveReason

인용

paused

종료 게이트를 안 타고 멈춤. 자산이 아직 폴더 안에 있다

가능

discarded

폐기 + 종료를 마친 껍데기

금지

resumeBy를 함께 답니다. 그 날짜를 넘기면 폐기 후보가 되고요.

여기서 판단이 하나 있었는데, 정상 종료도 discarded입니다. 종료 게이트를 통과하면 자산이 전부 계층으로 빠져나가서 폐기와 처지가 같아지거든요. 다른 것은 paused뿐입니다.

폴더로 안 가르고 필드로 가른 이유도 적어뒀습니다. 폴더는 사람만 보고 뷰는 필드로 거릅니다. 폴더로만 나누면 trustLevel 필터에서 pauseddiscarded와 함께 걸려버려요.

정의는 SCHEMA.local.md §3, 분류 분기는 ROUTER.local.md Q8에 있습니다.


3. 다음 단계

3단 파이프라인 설계를 문서 12건으로 착수했습니다. 승격 게이트, 수집 헌장, 가정 감시 등이 여기 들어갑니다.

오늘 얻은 두 가지가 그 전제예요. 사람이 붙을 수 있는 진입점, 그리고 upstream을 계속 받으면서 내 필요를 채우는 방법.


교훈

1. 원본 파일은 건드리지 말고, 내 작업은 옆에 따로 두자. 원본을 직접 고치면 나중에 업데이트를 받을 때마다 내 수정과 뒤섞여 충돌이 납니다. 한두 번은 손으로 풀 수 있지만 쌓이면 결국 업데이트를 안 받게 되고, 그러면 잘 만들어진 시스템에 올라탄 이점이 통째로 사라져요.

방법은 1) 규칙을 넓힐 땐 .local 확장 문서를 옆에 두고, 2) 기록이 섞이면 파일을 갈라 담고, 3) 스키마에 안 맞는 건 본문에 적고, 4) 한 값이 두 뜻을 지면 필드를 하나 더해 가르는 것입니다. 넷 다 원본을 한 글자도 안 건드립니다.

2. 어려운 시스템을 동료에게 권하려면, 개념을 가르치지 말고 입구를 만들자. "7계층을 익히세요"가 아니라 "이 노트 하나만 여세요"가 되어야 합니다.


참고

1
2개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.