문서와 심볼

aidlc-docs 를 그대로 읽는다 · 읽기 전용
/home/sunny/enode-fixup-workshop2-visualizer연결 중
inception/reverse-engineering/dependencies.md180 줄

enode — 의존 관계

외부 3 + 7, 내부 15개 패키지의 교차 의존. go.mod 와 실제 import 를 직접
확인했다.

외부 직접 의존 (3)

require (
    github.com/jackc/pgx/v5 v5.10.0
    golang.org/x/sys        v0.47.0
    gopkg.in/yaml.v3        v3.0.1
)
라이브러리 버전 어디서 쓰나 왜 필요한가
github.com/jackc/pgx/v5 v5.10.0 internal/store 전용 PostgreSQL 드라이버와 pgxpool 커넥션 풀. SKIP LOCKED · 세이브포인트 · LISTEN/NOTIFY 같은 Postgres 고유 기능을 쓰므로 database/sql 추상화 대신 직접 드라이버를 쓴다
golang.org/x/sys v0.47.0 internal/enode/lock_unix.go · lock_windows.go · disk_unix.go · disk_windows.go 파일 잠금(flock / LockFileEx)과 디스크 여유 측정. 표준 라이브러리에 없는 syscall
gopkg.in/yaml.v3 v3.0.1 internal/config · internal/enode/config.go Mediator 설정과 노드 local.yaml 파싱

의존이 셋뿐인 것이 우연이 아니다. 웹 프레임워크 · 테스트 프레임워크 · ORM ·
마이그레이션 도구 · assertion 라이브러리 · mock 라이브러리 · 로거를 전부 표준
라이브러리로 대신했다. 자세한 것은 technology-stack.md.

미사용 직접 의존 0건. 셋 전부 실사용된다.

외부 간접 의존 (7)

require (
    github.com/jackc/pgpassfile     v1.0.0                              // indirect
    github.com/jackc/pgservicefile  v0.0.0-20240606120523-5a60cdf6a761  // indirect
    github.com/jackc/puddle/v2      v2.2.2                              // indirect
    github.com/kr/text              v0.2.0                              // indirect
    github.com/rogpeppe/go-internal v1.16.0                             // indirect
    golang.org/x/sync               v0.17.0                             // indirect
    golang.org/x/text               v0.29.0                             // indirect
)
라이브러리 누가 끌고 오나
jackc/pgpassfile · jackc/pgservicefile · jackc/puddle/v2 pgx/v5
golang.org/x/sync · golang.org/x/text pgx/v5
kr/text · rogpeppe/go-internal 테스트 경로

전이 의존 트리의 깊이가 얕다. 직접 3개 밖에 붙는 것이 7개뿐이라 공급망 표면이
작다.

내부 교차 의존

전체 그래프

   cmd/mediator    ──▶  internal/api
                   ──▶  internal/store
                   ──▶  internal/record
                   ──▶  internal/config
                   ──▶  internal/build

   cmd/enode       ──▶  internal/enode
                   ──▶  internal/build

   cmd/enodectl    ──▶  internal/enode
                   ──▶  internal/build

   cmd/runctl      ──▶  internal/runctl
                   ──▶  internal/build

   cmd/iapadapter  ──▶  (내부 의존 없음)

   internal/api    ──▶  internal/config
                   ──▶  internal/contract
                   ──▶  internal/match
                   ──▶  internal/record
                   ──▶  internal/schema
                   ──▶  internal/store

   internal/store  ──▶  internal/contract
                   ──▶  internal/match
                   ──▶  internal/record

   internal/enode  ──▶  internal/contract

   internal/match  ──▶  internal/contract

   internal/contract  internal/record  internal/schema
   internal/config    internal/build   internal/runctl
                   ──▶  (내부 의존 없음)

층위

의존이 정확히 세 층으로 갈린다.

층 패키지 성질
3 — 실행파일 cmd/* 5개 배선만 한다. 로직이 거의 없다
2 — 조립 internal/api · internal/store · internal/enode 아래 층을 조립해 동작을 만든다
1 — 어휘와 도구 internal/contract · record · schema · config · build · match · runctl 내부 의존이 0이거나 contract 하나뿐

internal/match 만 1층 안에서 internal/contract 를 부른다. 그 외 1층
패키지들은 서로를 부르지 않는다.

의존 방향의 불변 — 코드로 강제되는 것

순환 0건

계측 확인. go build ./... 가 통과하는 이상 Go 가 순환 import 를 허용하지
않으므로 이것은 구조적으로 보장된다.

internal/enode 는 internal/store · internal/api 를 못 본다

   internal/enode  ──import──▶  internal/contract      (이것뿐)
   internal/enode      import 하지 않음     internal/store
   internal/enode      import 하지 않음     internal/api

이 저장소에서 가장 중요한 의존 사실이다. 노드가 Mediator 내부를 못 보는 것이
규약이 아니라 컴파일러가 지키는 사실이다. 노드는 Mediator 를 HTTP 표면으로만
안다.

같은 방향으로 internal/store 도 internal/api 를 모른다. 의존은 언제나
바깥(표면)에서 안(상태)으로만 흐른다.

cmd/iapadapter 는 내부 의존이 0이다

바깥 트래커를 아는 유일한 부품이 내부 패키지를 하나도 import 하지 않고 자기
안에서 HTTP 로 Mediator 와 말한다. 어댑터를 갈아 끼워도 나머지가 안 흔들린다.

대가: 계약 타입과 라우트 문자열을 자기 안에 다시 갖는다. Mediator 표면이
바뀌면 어댑터가 컴파일 오류로 알려주지 않고 런타임에 깨진다.

공유 어휘 — internal/contract 의 자리

네 컴포넌트가 공유하는 유일한 타입 정의다.

   internal/api    ──▶ ┐
   internal/store  ──▶ ├──▶  internal/contract
   internal/enode  ──▶ │
   internal/match  ──▶ ┘

Contract · Step · Condition · Ask · See · Ledger · Work 가 여기
살고, Contract.Validate()(612줄)가 문법 전체의 단일 검증 지점이다. 이 패키지가
바뀌면 넷이 함께 바뀐다 — 실제로 가장 큰 결합 지점이다.

데이터 저장소 의존

저장소 붙는 컴포넌트 버전
PostgreSQL internal/store (via pgx/v5) 17
파일시스템 (Mediator) internal/record —
파일시스템 (노드) internal/enode —

internal/record 는 DB 를 모르고 internal/store 는 Record 를 internal/record
인터페이스로만 본다.

프로세스 외부 의존

대상 부르는 곳 필수
claude CLI internal/enode/runner.go:54 runHarness (유일한 exec 지점) 아니오 — 없으면 광고에서 빠진다
git internal/enode/workspace.go · diff.go 아니오
sh 명령 단계 실행 명령 단계에만
notify.asks_url 웹훅 internal/store/ask.go:102 PushAsks 아니오 — 설정됐을 때만

Mediator 가 바깥으로 거는 호출은 asks 웹훅 하나뿐이고, 재시도가 없다.

관측

  • 미사용 의존 0건, 순환 0건, 하드코딩된 자격증명 0건
  • 의존 트리가 얕고 좁다 — 직접 3 · 간접 7. 이 규모(27,211 LOC)의 Go 프로젝트로는
    드물게 적다
  • 가장 큰 결합은 외부가 아니라 내부에 있다: internal/contract 가 넷을 묶고,
    그 안의 Validate() 612줄이 문법 변경의 단일 통과점이다