<a id="dependency-reference"></a>
# 직접 의존성·빌드 계약

이 페이지는 고정 source revision의 direct dependency와 build/package 입력을 이름 단위로 고정한다. Go direct 12개, web runtime direct 41개, web development direct 15개로 **direct dependency 분모는 68개**다. Go `go.mod` explicit require는 53개(12 direct+41 `// indirect`)지만 selected build list는 root 제외 183개이고 현재 production import closure는 49 module이다. npm lock은 773 record(root 1+external package location 772)다. Exact 전이/version index는 [전이 의존성·lock 전수 색인](dependency-lock.md#dependency-lock-reference)이 소유한다. [Go manifest](evidence:go-module) [web manifest](evidence:web-package) [web lock](evidence:web-lock)

`go.mod`의 version은 module selection 입력이다. `package.json`의 caret range는 허용 범위이고, 아래 “lock”은 이 revision의 `package-lock.json`이 선택한 exact version이다.

<a id="go-direct-dependencies"></a>
## Go direct dependency: 12개

| module | version | 소비자·역할 |
|---|---|---|
| `github.com/Autumn-27/norma` | `v0.4.3` | LLM provider/session, tools, Skill/MCP, transcript/context runtime |
| `github.com/golang-jwt/jwt/v5` | `v5.3.1` | HS JWT parse/sign |
| `github.com/google/uuid` | `v1.6.0` | request/session/file identity |
| `github.com/jackc/pgx/v5` | `v5.10.0` | PostgreSQL driver/pool |
| `github.com/klauspost/compress` | `v1.18.6` | task archive Zstandard stream |
| `github.com/lqqyt2423/go-mitmproxy` | `v1.9.2` | HTTP(S) recording proxy/MITM |
| `github.com/miekg/dns` | `v1.1.72` | DNS wire/client support |
| `github.com/projectdiscovery/dnsx` | `v1.2.3` | asset DNS enrichment |
| `golang.org/x/crypto` | `v0.55.0` | bcrypt and crypto helpers |
| `golang.org/x/net` | `v0.58.0` | network/public-suffix helpers |
| `golang.org/x/text` | `v0.41.0` | text/encoding helpers |
| `modernc.org/sqlite` | `v1.52.0` | CGO-free traffic SQLite |

Module은 `go 1.26.3`을 선언하고 build script는 Go 1.26 이상을 요구한다. `CGO_ENABLED=0`과 `embedui` tag가 release binary 계약이다.

`go.mod`의 explicit indirect 41개는 [manifest 목록](dependency-lock.md#go-indirect-dependencies), 전체 183개는 [selected build list](dependency-lock.md#go-selected-build-list), 실제 package import가 나타난 49 module은 [production import closure](dependency-lock.md#go-production-import-closure)에서 분리해 본다. `go.sum` checksum 행은 어느 dependency 분모와도 같지 않다.

<a id="web-runtime-dependencies"></a>
## Web direct runtime dependency: 41개

| package | manifest range | lock | 주 역할 |
|---|---:|---:|---|
| `@antv/g6` | `^5.1.1` | `5.1.1` | graph rendering engine |
| `@antv/graphin` | `^3.0.5` | `3.0.5` | React graph view |
| `@base-ui/react` | `^1.6.0` | `1.6.0` | unstyled UI primitive |
| `@dnd-kit/core` | `^6.3.1` | `6.3.1` | drag/drop core |
| `@dnd-kit/modifiers` | `^9.0.0` | `9.0.0` | drag/drop modifiers |
| `@dnd-kit/sortable` | `^10.0.0` | `10.0.0` | sortable interactions |
| `@fullcalendar/react` | `^7.0.0` | `7.0.0` | calendar UI |
| `@hookform/resolvers` | `^5.4.0` | `5.4.0` | form schema adapters |
| `@shadcn/react` | `^0.1.0` | `0.1.0` | component registry/runtime |
| `@tanstack/react-table` | `^8.21.3` | `8.21.3` | table model |
| `@xyflow/react` | `^12.3.0` | `12.11.1` | node/edge flow UI |
| `class-variance-authority` | `^0.7.1` | `0.7.1` | component variants |
| `clsx` | `^2.1.1` | `2.1.1` | class composition |
| `cmdk` | `^1.1.1` | `1.1.1` | command palette |
| `d3-geo` | `^3.1.1` | `3.1.1` | geographic projection |
| `date-fns` | `^4.4.0` | `4.4.0` | date operations |
| `embla-carousel-react` | `^8.6.0` | `8.6.0` | carousel |
| `geist` | `^1.7.2` | `1.7.2` | font package |
| `input-otp` | `^1.4.2` | `1.4.2` | OTP input |
| `lucide-react` | `^1.22.0` | `1.22.0` | icons |
| `next` | `^16.2.9` | `16.2.9` | App Router/build/server framework |
| `next-themes` | `^0.4.6` | `0.4.6` | theme state |
| `radix-ui` | `^1.6.0` | `1.6.0` | UI primitives |
| `react` | `^19.2.7` | `19.2.7` | component runtime |
| `react-day-picker` | `^10.0.1` | `10.0.1` | date picker |
| `react-dom` | `^19.2.7` | `19.2.7` | DOM renderer |
| `react-hook-form` | `^7.80.0` | `7.80.0` | form state |
| `react-is` | `^19.2.7` | `19.2.7` | React element inspection |
| `react-markdown` | `^10.1.0` | `10.1.0` | Markdown rendering |
| `react-resizable-panels` | `^4.12.0` | `4.12.0` | resizable layout |
| `recharts` | `^3.8.0` | `3.8.0` | charts |
| `remark-gfm` | `^4.0.1` | `4.0.1` | GFM parsing plugin |
| `shadcn` | `^4.12.0` | `4.12.0` | shadcn registry tooling/runtime dependency |
| `simple-icons` | `^16.24.1` | `16.24.1` | brand icons |
| `sonner` | `^2.0.7` | `2.0.7` | toast UI |
| `tailwind-merge` | `^3.6.0` | `3.6.0` | Tailwind class merging |
| `temporal-polyfill` | `^1.0.1` | `1.0.1` | Temporal date/time polyfill |
| `topojson-client` | `^3.1.0` | `3.1.0` | TopoJSON decode |
| `vaul` | `^1.1.2` | `1.1.2` | drawer UI |
| `zod` | `^4.4.3` | `4.4.3` | runtime schema validation |
| `zustand` | `^5.0.14` | `5.0.14` | client state store |

이 41개는 root manifest의 runtime direct 분모다. 현재 lock의 direct·transitive package location 772개와 project-root record 1개는 [npm lock 전수 색인](dependency-lock.md#web-lock-summary)에서 exact version과 분류로 접근한다.

<a id="web-dev-dependencies"></a>
## Web direct development dependency: 15개

| package | manifest range | lock | 주 역할 |
|---|---:|---:|---|
| `@biomejs/biome` | `^2.5.1` | `2.5.1` | lint/format/check |
| `@tailwindcss/postcss` | `^4.3.2` | `4.3.2` | Tailwind PostCSS plugin |
| `@types/d3-geo` | `^3.1.0` | `3.1.0` | TypeScript declarations |
| `@types/node` | `^22.20.0` | `22.20.0` | TypeScript declarations |
| `@types/react` | `^19.2.17` | `19.2.17` | TypeScript declarations |
| `@types/react-dom` | `^19.2.3` | `19.2.3` | TypeScript declarations |
| `@types/topojson-client` | `^3.1.5` | `3.1.5` | TypeScript declarations |
| `babel-plugin-react-compiler` | `^1.0.0` | `1.0.0` | React compiler transform |
| `husky` | `^9.1.7` | `9.1.7` | Git hook installation |
| `lint-staged` | `^16.4.0` | `16.4.0` | staged-file checks |
| `postcss` | `^8.5.16` | `8.5.16` | CSS transform runner |
| `tailwindcss` | `^4.1.5` | `4.3.2` | utility CSS compiler |
| `ts-node` | `^10.9.2` | `10.9.2` | theme preset TypeScript script |
| `tw-animate-css` | `^1.4.0` | `1.4.0` | animation utilities |
| `typescript` | `^5.9.3` | `5.9.3` | type checker/compiler |

<a id="web-script-contract"></a>
### `web/package.json` script: 10개

| script | command | 기능 |
|---|---|---|
| `dev` | `next dev` | development server |
| `build` | `next build` | configured Next build |
| `build:static` | `NEXT_EXPORT=1 next build` | static export for embedding |
| `start` | `next start` | production Next server |
| `lint` | `biome lint` | lint |
| `format` | `biome format --write` | format/write |
| `check` | `biome check` | combined check |
| `check:fix` | `biome check --write` | combined check/fix |
| `prepare` | `husky` | Git hook setup during install |
| `generate:presets` | `ts-node -P tsconfig.scripts.json src/scripts/generate-theme-presets.ts` | theme preset generation |

<a id="build-contract"></a>
## `build.sh` CLI와 환경변수

`build.sh` option concept는 5개다. Unknown option과 값 없는 `--target`은 exit 1이고, help는 exit 0이다. CLI가 대응 환경변수를 덮어쓴다. [build script](evidence:build-script)

| option | 인자·기본 | override·효과 |
|---|---|---|
| `--release` | flag, off | `ARTEX_RELEASE=1`, `ARTEX_PACKAGE=1`; multi-target release |
| `--target OS/ARCH` | one value | `ARTEX_TARGET_OS`, `ARTEX_TARGET_ARCH`, `ARTEX_TARGETS`를 그 pair로 설정 |
| `--upx` | flag | `ARTEX_COMPRESS=required`; UPX가 없거나 실패하면 build 실패 |
| `--no-compress` | flag | `ARTEX_COMPRESS=0`; UPX 단계 생략 |
| `--help`, `-h` | flag | usage 출력 후 종료 |

Environment control은 정확히 14개다.

| 이름 | 타입·기본값 | 소비 조건·효과 |
|---|---|---|
| `ARTEX_RELEASE` | bool-like string, `0` | 정확히 `1`이면 release mode와 release target default 사용 |
| `ARTEX_TARGET_OS` | GOOS, single mode에서 `go env GOOS` | single-target OS; `--target`가 덮어씀 |
| `ARTEX_TARGET_ARCH` | GOARCH, single mode에서 `go env GOARCH` | single-target arch; `--target`가 덮어씀 |
| `ARTEX_TARGETS` | comma list; single은 OS/ARCH, release는 5-target list | 실제 build loop; 공백 제거, 각 값은 `OS/ARCH`여야 함 |
| `ARTEX_BUILD_VERSION` | string; `git describe --tags --always --dirty`, 아니면 `dev` | leading `v` 제거 후 binary ldflag와 archive name에 사용 |
| `ARTEX_OUTPUT` | path, unset | non-release single-target binary path만 직접 지정 |
| `ARTEX_OUTPUT_DIR` | path, `dist` | 기본 binary directory |
| `ARTEX_PACKAGE` | bool-like string, `0` | 정확히 `1`이면 target별 zip과 checksum 생성; `--release`가 `1`로 강제 |
| `ARTEX_PACKAGE_DIR` | path, output dir | release directory와 `SHA256SUMS` 위치 |
| `ARTEX_COMPRESS` | enum `off|auto|required`, `off` | UPX 정책; `0|false|none`도 off, `true|1`도 enabled로 해석 |
| `ARTEX_UPX_ARGS` | shell words, `--best --lzma` | UPX 인자; Darwin은 `--force-macos` 추가 |
| `ARTEX_SKIP_FRONTEND` | bool-like string, `0` | 정확히 `1`이면 rebuild를 생략하고 기존 `server/webui/dist`가 없으면 실패 |
| `ARTEX_SKIP_NPM_CI` | bool-like string, `0` | 정확히 `1`이면 frontend rebuild 전에 `npm ci`만 생략 |
| `ARTEX_GOSUMDB` | string, `sum.golang.org` | `go env`와 `go build` checksum DB |

Release default target은 `linux/amd64`, `linux/arm64`, `darwin/amd64`, `darwin/arm64`, `windows/amd64` 5개다. Frontend rebuild에는 `npm`과 `rsync`, package에는 `zip`이 필수다. `upx`, `git`, `file`, `sha256sum`/`shasum`은 선택 경로다. Zip에는 target binary, 해당 OS의 start wrapper, `skills/`, `config.example.json`, 존재하면 `README.md`가 들어간다.

<a id="compose-inputs"></a>
## Compose `.env` input: 10개

| 이름 | 기본·필수 | container 효과 |
|---|---|---|
| `ARTEX_TAG` | `latest` | `autumn27/artex:<tag>` 선택 |
| `POSTGRES_USER` | `artex` | PostgreSQL init/user와 generated `ARTEX_PG_DSN` |
| `POSTGRES_PASSWORD` | 필수, 기본 없음 | PostgreSQL init/password와 generated DSN |
| `POSTGRES_DB` | `artex` | PostgreSQL init/database와 generated DSN |
| `ANTHROPIC_API_KEY` | empty | Go runtime fallback provider |
| `OPENAI_API_KEY` | empty | Go runtime fallback provider |
| `ARTEX_LLM_PROVIDER` | empty | Go runtime fallback format |
| `ARTEX_LLM_MODEL` | empty | fallback model override |
| `ARTEX_LLM_BASE_URL` | empty | fallback endpoint override |
| `ARTEX_LLM_PROXY` | empty | fallback LLM egress proxy |

Compose가 `ARTEX_PG_DSN`을 위 세 PostgreSQL input으로 조립하므로 이는 별도 `.env` input이 아니다. `./data`와 `./skills`를 mount하고 `pgdata` named volume을 쓴다. Container의 `/app/jwt.key`는 `/app/data` mount 밖이므로 현재 선언만으로 유지되지 않는다. [Compose](evidence:compose)

<a id="toolchain-images"></a>
## CI·container toolchain 경계

| 면 | pinned/declared 값 | 계약 |
|---|---|---|
| release frontend | Node `22` | `npm ci`, static export artifact |
| release binaries | Go `1.26`, 5-target matrix | `build.sh --target`, zip, Linux amd64 smoke `-h` |
| release image | linux amd64/arm64 | prebuilt binaries를 Buildx로 Docker Hub에 push |
| runtime base | `python:3.12-slim-bookworm`, NodeSource `20.x` | Python custom scripts, npm/npx/browser tooling |
| browser packages | `@playwright/mcp@latest`, `@playwright/cli@latest`, `playwright@latest` | image build 때 unpinned latest 설치와 Chromium preload |

Release workflow의 Node 22와 runtime image의 Node 20은 서로 다른 단계다. `latest` browser packages는 source revision만으로 exact resolved version을 재현하지 못한다. [Dockerfile](evidence:dockerfile) [release workflow](evidence:release-workflow)
