Grotto: Neander 프로그램이 살아가는 곳
요약
에이전트 우선 프로그래밍 언어인 Neander를 실행하기 위한 런타임 참조 구현체인 Grotto를 소개합니다. Node.js 기반의 TypeScript 라이브러리로, 보안을 위해 외부 의존성을 완전히 배제한 아키텍처 설계를 특징으로 합니다.
핵심 포인트
- Neander 언어의 모든 표현식과 데이터 타입을 실행하는 런타임 구현체
- Node.js 내장 기능만 사용하여 공급망 공격을 원천 차단하는 보안 설계
- 아키텍처 명세서와 기술 설계 문서를 기반으로 한 체계적인 개발 프로세스
- 에이전트와 호스트 사이에서 신뢰할 수 있는 구성 요소 역할 수행
지난번 Neander: 에이전트 우선 프로그래밍 언어 (An Agent-First Programming Language)에서 저는 언어를 발표했지만, 이를 실제로 작동시키기 위해 호스트(host)에게 정말로 필요한 한 가지, 즉 런타임 참조 구현체 (runtime reference implementation)는 발표하지 않았습니다. 저는 이것이 이미 존재하며 다음번에 보여드리겠다고 약속했습니다.
여기 있습니다.
이것의 이름은 Grotto입니다. 명명 규칙은 테마를 유지합니다. 최초의 네안데르탈인 화석은 grotto, 즉 "네안데르탈인이 살았던 곳"에서 발견되었습니다. Grotto는 Neander 프로그램이 살고 실행되는 곳입니다.
명세서 (specification)는 계획입니다. 참조 구현체 (reference implementation)는 그 계획이 실행될 수 있다는 증거입니다. Grotto가 바로 그 증거입니다. Node.js에서 실행되는 임베디드 가능한 TypeScript 라이브러리로, Neander 프로그램을 일반 텍스트로 받아 명세서가 정의하는 언어 전체를 처음부터 끝까지, 모든 표현식 (expression), 모든 데이터 타입 (data type), 그리고 모든 내장 함수 (built-in function)를 실행합니다.
신뢰할 수 있는 구성 요소 (The trusted component)
지난 두 포스트의 설정을 떠올려 보십시오. 에이전트 (agent)는 외부에 있으며, 신뢰할 수 없고, 작은 프로그램들을 작성합니다. 호스트 (host)는 내부에 있으며, 호출할 가치가 있는 API들을 가지고 있습니다. 그들 사이에는 런타임 (runtime)이 자리 잡고 있으며, 런타임은 이 전체 구조에서 모든 사람이 반드시 신뢰해야 하는 유일한 구성 요소입니다.
그것은 매우 무거운 왕관을 쓰는 것과 같습니다. Grotto의 설계 전체는 그 신뢰가 정당하다는 논거를 담고 있습니다.
이는 설계 프로세스 자체에서 시작됩니다. Grotto는 분위기에 따라 코딩된 것 (vibe coded)이 아니라, 아키텍처 설계 (architected)되었습니다. 저는 공인 소프트웨어 아키텍트 (iSAQB® CPSA-Advanced Level)이므로, 컨디션이 좋은 날에는 제가 무엇을 하고 있는지 정확히 알고 있습니다. Grotto 구현은 아키텍처 명세서 (arc42, C4)와 기술 설계 문서 (technical design document, 저와 에이전트가 공동 작성)를 만드는 것으로 시작되었습니다. 그 후에야 코딩 에이전트 (coding agent)가 코드베이스 (codebase)를 생성했습니다.
그다음은 의존성(dependencies), 더 정확히 말하자면 의존성의 부재로 이어집니다. Grotto는 런타임 의존성(runtime dependencies)이 '전혀' 없으며, 오직 Node 내장 기능(built-ins)에만 의존합니다. 이는 단순히 정리 정돈 차원이 아니라 보안 경계(security boundary)를 구축하는 것입니다. 설치하지 않은 npm 패키지는 당신을 공격할 수 없습니다. 의존성을 통해 Grotto에 도달할 수 있는 통로 자체가 없기 때문에, 어떠한 CVE, 침해된 유지관리자(compromised maintainer), 또는 공급망 공격(supply-chain attack)도 Grotto에 닿을 수 없습니다. 결국 Grotto 자체의 코드만 남게 되며, 그 설계가 나머지 논쟁을 종결시킵니다.
호스트와 맞닿는 라이브러리는 200줄 미만의 작은 디스패처(dispatcher)이며, 언어 코드(language code)를 전혀 포함하지 않습니다. 타인의 프로그램에 실제로 접촉하는 모든 요소 — 렉서(lexer), 파서(parser), 검증기(validator), 인터프리터(interpreter) — 는 완전히 다른 곳에서 실행됩니다. 즉, 해당 제출 건을 위해 생성되었다가 작업이 완료되는 즉시 폐기되는 새로운 워커 스레드(worker thread)에서 실행됩니다. 이는 단순한 예의가 아닌, 구조에 의한 격리(Isolation by construction)입니다. 이를 모두 합산해 보면, 임베딩 애플리케이션(embedding application)의 자체 스레드에서 실행되는 유일한 Grotto 코드는 그 작은 디스패처뿐입니다. 그 외의 모든 것은 종료할 수 있는 격리된 워커(isolated worker)에 격리됩니다.
모든 프로그램은 Neander 명세(spec)에서 규정한 예산 시스템(budget system)의 엄격한 상한선 아래에서 실행됩니다. 계산(computation), 메모리(memory), 그리고 실제 경과 시간(wall-clock time)에 대한 제한이 적용됩니다. 시간 제한을 초과하면 워커는 단순히 종료됩니다. 디스패처가 시계를 관리하므로, 프로그램이 멈춰버리더라도(wedged program) 디스패처보다 오래 버틸 수는 없습니다. 언어 자체에 재귀(recursion)와 무한 루프(unbounded loops)가 없으므로, 종료(termination) 여부는 애초에 의심의 여지가 없었습니다. 예산은 그 외의 모든 상황을 위해 존재합니다.
마지막 방어선은 품질 보증(quality assurance)입니다. 지금까지 Grotto의 명세와 코드베이스는 여러 최첨단 코딩 모델(frontier coding models)인 Opus 4.6–4.8, GPT-5.5, 그리고 순전한 운으로 Fable 5에 의해 검토되었습니다.
코드베이스의 품질은 1,300개 이상의 유닛 테스트(unit tests, 커버리지 > 90%이지만 백분율 수치에만 너무 흥분하지는 맙시다)와 Neander 적합성 테스트 스위트(conformance test suite)를 향해 지속적으로 확장되고 있는 750개 이상의 블랙박스 엔드 투 엔드 테스트(black-box end-to-end tests, 프로그램 제출)를 통해 검증됩니다.
여러분은 언제든 더 많은 것을 할 수 있으며, 저 또한 그럴 것입니다. 하지만 기초 작업은 완료되었습니다. Grotto를 실제 호스트 애플리케이션에 도입할지 고민하는 사람이라면 누구나 Grotto와 Neander를 진지하게 고려할 수 있을 만큼 충분히 준비되었다고 희망합니다.
분명히 말씀드리자면, 아직 초기 단계입니다. 사양(spec)은 여전히 초안 상태이며, 버전 번호는 0으로 시작하고, 인터페이스는 변경될 수 있습니다. 하지만 이것은 실재하며, 로드맵이 아닌 오늘 바로 실행 가능한 런타임(runtime)입니다.
활용 방법
Neander는 에이전트(agent)만이 작성하기 때문에 읽기 이상하게 느껴질 수 있지만, Grotto는 인간만이 호스트(host)하기 때문에 정상적으로 읽힙니다. 라이브러리를 임베드(embed)하고, 여러분의 API를 프로바이더 모듈(provider modules)로 전달한 뒤, 에이전트가 이를 가리키도록 설정하면 됩니다:
import { Runtime } from 'grotto1';
const runtime = await Runtime.start({
...
모든 제출(submission)은 하나의 구조화된 엔벨로프(envelope)로 반환됩니다. 즉, 반환된 값 또는 실패한 정확한 방식(타입 체크에 실패한 프로그램, 에러가 발생한 호출, 소진된 예산 등)이 포함됩니다. 매번 하나의 프로그램이 입력되면, 항상 하나의 잘 구성된 답변이 출력됩니다. 아무것도 유출되지 않으며, 아무것도 멈추지(hang) 않습니다.
Grotto에서의 현장 노트
다뤄야 할 내용이 훨씬 더 많습니다. 에이전트가 런타임에서 어떻게 여러분의 API를 발견하는지, 프로그램이 요금을 과다하게 발생시키지 않도록 방지하는 예산(budget) 시스템, 낯선 사람의 코드를 실행할 수 있게 해주는 워커 격리(worker isolation) 등이 있습니다. 각각의 주제는 그 자체로 포스팅할 가치가 있기에, Neander 언어와 그 런타임에 대해 기능별로 다루는 새로운 시리즈를 시작하려 합니다.
그동안 Grotto는 GitHub에 공개되어 있으며, 라이선스는 허용적(permissive)이고, 모든 가능성은 열려 있습니다. 여러분의 앱에 임베드해 보시고, 무엇이 작동하지 않는지 저에게 알려주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기