update agent-ops rules and roadmap, bin scripts, README, docs

This commit is contained in:
toki 2026-05-24 21:08:07 +09:00
parent 19f7528365
commit 3a6c9fb627
13 changed files with 42 additions and 89 deletions

View file

@ -1,14 +1,14 @@
# NomadCode
NomadCode는 AI 기반 개발 작업을 제품 흐름으로 운영하기 위한 원레포입니다. Go 기반 core 서비스, React/Vite 웹 콘솔, Flutter 클라이언트, 공유 계약 공간, 그리고 AI 에이전트 작업 규칙과 로드맵을 한 작업 흐름으로 묶습니다.
NomadCode는 AI 기반 개발 작업을 제품 흐름으로 운영하기 위한 원레포입니다. Go 기반 core 서비스, Flutter 앱, 공유 계약 공간, 그리고 AI 에이전트 작업 규칙과 로드맵을 한 작업 흐름으로 묶습니다.
NomadCode는 IOP를 사용하는 개발 워크플로우 셸입니다. 사용자와 외부 provider 요청을 개발 작업으로 구조화하고, project/session/workspace 상태와 실행 결과를 사용자에게 보여줍니다. 모델 런타임, 모델 라우팅, RAG, MCP 정책, output validation 엔진은 NomadCode가 직접 소유하지 않고 IOP 책임으로 둡니다.
## 현재 상태
- `services/core`는 health/readiness endpoint, task API, PostgreSQL persistence, goose migration, sqlc query 생성 구조, River job, IOP OpenAI-compatible Responses client 경로, 향후 A2A agent delegation scaffolding, Plane/Mattermost adapter stub을 포함합니다.
- `apps/web`은 Agent, Projects, Settings, browser-based project workspace 화면을 위한 React/Vite 운영 콘솔 scaffold입니다. 일부 상태와 integration status 영역은 아직 mock 또는 stub입니다.
- `apps/mobile`은 Flutter 기반 모바일/데스크톱 클라이언트 scaffold이며 Firebase Messaging, local notifications, HTTP client 의존성을 포함합니다.
- `apps/mobile`은 NomadCode 제품 UI의 기준 Flutter 앱이며 모바일/데스크톱/선택적 web target, Firebase Messaging, local notifications, HTTP client 의존성을 포함합니다.
- `apps/web`은 이전 React/Vite 운영 콘솔 scaffold입니다. 장기 제품 UI 경로에서는 제외하며, Flutter-first 전환 과정에서 제거 또는 격리 대상으로 둡니다.
- `packages/contracts`는 향후 OpenAPI, protobuf, generated client, fixture, compatibility asset을 담을 공유 계약 공간입니다.
- 활성 계획과 Milestone 상태는 `agent-ops/roadmap/`에서 관리합니다. README에는 현재 작업 상태를 복사하지 않고 진입 문서만 연결합니다.
@ -19,7 +19,7 @@ NomadCode는 제품과 워크플로우 계층을 소유합니다.
- agent chat, project workspace 관리, task queue 상태, 실행 상태 표시
- Plane/Jira 스타일 work item intake, provider projection, comment, status update
- 사용자에게 노출되는 file change, diff, branch, commit, PR 흐름
- 데스크톱/모바일 project management surface
- 모바일/데스크톱/선택적 web target의 Flutter project management surface
- IOP 호출에 넘길 task metadata 구성
IOP는 실행과 최적화 계층을 소유합니다.
@ -53,14 +53,6 @@ cd services/core
./bin/run
```
Web console을 실행합니다.
```bash
cd apps/web
npm install
npm run dev
```
Flutter 앱을 실행합니다.
```bash
@ -73,17 +65,14 @@ flutter run
| 목적 | 명령 | 비고 |
|------|------|------|
| 개발 entrypoint 확인 | `bin/dev` | core, web, mobile 실행 명령을 출력합니다. |
| workspace 테스트 | `bin/test` | `go test ./...`, web check 또는 test, `flutter test`를 실행하고 없는 toolchain은 건너뜁니다. |
| workspace lint | `bin/lint` | `go vet ./...`, web lint, `flutter analyze --no-fatal-infos`를 실행하고 없는 toolchain은 건너뜁니다. |
| workspace build | `bin/build` | core `go build ./...`, web build, Flutter web build를 실행하고 없는 toolchain은 건너뜁니다. |
| 개발 entrypoint 확인 | `bin/dev` | core와 Flutter app 실행 명령을 출력합니다. |
| workspace 테스트 | `bin/test` | `go test ./...`, `flutter test`를 실행하고 없는 toolchain은 건너뜁니다. |
| workspace lint | `bin/lint` | `go vet ./...`, `flutter analyze --no-fatal-infos`를 실행하고 없는 toolchain은 건너뜁니다. |
| workspace build | `bin/build` | core `go build ./...`, Flutter web build를 실행하고 없는 toolchain은 건너뜁니다. |
| core 실행 | `cd services/core && ./bin/run` | 스크립트 기본값을 사용하며 env로 override할 수 있습니다. |
| core DB migration | `cd services/core && ./bin/migrate-up` | goose로 PostgreSQL migration을 적용합니다. |
| core 테스트 | `cd services/core && ./bin/test` | `go test ./...` wrapper입니다. |
| core build | `cd services/core && ./bin/build` | 기본 출력 경로는 `.build/nomadcode-core`입니다. |
| web dev server | `cd apps/web && npm run dev` | Vite 개발 서버입니다. |
| web type check | `cd apps/web && npm run check` | TypeScript `--noEmit` 검증입니다. |
| web verify | `cd apps/web && npm run verify` | type check와 production build를 함께 실행합니다. |
| mobile 테스트 | `cd apps/mobile && flutter test` | Flutter test suite입니다. |
## 구조
@ -91,8 +80,8 @@ flutter run
| 경로 | 역할 |
|------|------|
| `services/core/` | Go backend. orchestration, persistence, scheduling, HTTP API, 외부 service adapter를 담당합니다. |
| `apps/web/` | React/Vite 운영 콘솔과 agent/project workspace UI입니다. |
| `apps/mobile/` | Flutter 모바일/데스크톱 클라이언트와 notification 연동 표면입니다. |
| `apps/mobile/` | Flutter 기반 제품 UI source of truth, 모바일/데스크톱 클라이언트와 notification 연동 표면입니다. |
| `apps/web/` | 이전 React/Vite 운영 콘솔 scaffold입니다. 장기 제품 경로에서 제거 또는 격리할 대상입니다. |
| `packages/contracts/` | 서비스와 클라이언트가 공유할 API/schema 계약 공간입니다. |
| `docs/` | 아키텍처와 운영 문서입니다. |
| `bin/` | root test, lint, build, dev helper 명령입니다. |
@ -136,13 +125,10 @@ IOP 경계가 걸린 작업은 같은 workspace에 sibling IOP repository가 있
| Core | `WORKFLOW_TASK_TIMEOUT_SEC` | 선택 | workflow task timeout 기본값을 조정합니다. |
| Core | `MATTERMOST_BASE_URL`, `MATTERMOST_TOKEN` | 선택 | Mattermost adapter 연동용 설정입니다. |
| Core | `PLANE_BASE_URL`, `PLANE_TOKEN` | 선택 | Plane work item 조회, comment, state update 연동용 설정입니다. token 값은 문서에 기록하지 않습니다. |
| Web | `VITE_NOMADCODE_API_BASE_URL` | 선택 | web client API base URL입니다. 기본값은 `http://localhost:8080`입니다. |
## 참고 문서
- `docs/monorepo.md`
- `services/core/README.md`
- `apps/web/README.md`
- `apps/mobile/README.md`
- `packages/contracts/README.md`
- `agent-ops/roadmap/current.md`

View file

@ -20,7 +20,7 @@ NomadCode는 Flutter 기반 앱, core 서비스, 공유 계약, agent-operation
### Client Platform Consolidation
- [Flutter-first Client Consolidation](milestones/flutter-first-client-consolidation.md) - 상태: 계획; 목표: Flutter 앱을 제품 UI 기준 구현으로 세우고 React/Vite 웹 콘솔을 장기 제품 경로에서 걷어낸다.
- [Flutter-first Client Consolidation](milestones/flutter-first-client-consolidation.md) - 상태: 진행 중; 목표: Flutter 앱을 제품 UI 기준 구현으로 세우고 React/Vite 웹 콘솔을 장기 제품 경로에서 걷어낸다.
### Work Item Provider Pipeline Design

View file

@ -10,7 +10,7 @@ Client Platform Consolidation
## 상태
계획
진행 중
## 구현 잠금
@ -28,10 +28,10 @@ Client Platform Consolidation
## 필수 기능
- [ ] [ui-source] Flutter 앱을 제품 UI source of truth로 선언하고 React web을 기준 구현에서 제외한다.
- [x] [ui-source] Flutter 앱을 제품 UI source of truth로 선언하고 React web을 기준 구현에서 제외한다.
- [ ] [react-retire] `apps/web` React/Vite scaffold의 제거, 격리, 또는 폐기 경로를 정리한다.
- [ ] [entrypoints] root `bin/*` 개발/검증 entrypoint가 Flutter-first 클라이언트 구조를 반영하도록 한다.
- [ ] [docs-rules] README, docs, roadmap, domain rule의 web/app 설명을 Flutter-first 기준으로 맞춘다.
- [x] [entrypoints] root `bin/*` 개발/검증 entrypoint가 Flutter-first 클라이언트 구조를 반영하도록 한다.
- [x] [docs-rules] README, docs, roadmap, domain rule의 web/app 설명을 Flutter-first 기준으로 맞춘다.
- [ ] [codeserver-direct] code-server, workspace, diff/terminal/editor 표면은 React wrapper 없이 Flutter 앱에서 직접 연결하는 기준을 정한다.
- [ ] [contract-boundary] Flutter 앱과 core가 공유할 API/schema 경계를 `packages/contracts` 후보로 정리한다.

View file

@ -17,8 +17,8 @@ NomadCode 런타임 사이의 공유 계약 도메인이다. API schema, event s
## 제외 경로
- `services/core/internal/http/` — API implementation은 core 도메인이다.
- `apps/web/src/api/` — web-specific API client wrapper는 web 도메인이다.
- `apps/mobile/lib/` — mobile-specific client/service code는 mobile 도메인이다.
- `apps/web/src/api/` — legacy web-specific API client wrapper는 web 도메인이다.
## 주요 구성 요소
@ -27,15 +27,15 @@ NomadCode 런타임 사이의 공유 계약 도메인이다. API schema, event s
## 유지할 패턴
- 계약 변경은 additive를 우선한다.
- breaking change는 core, web, mobile 반영을 같은 branch에서 조율한다.
- breaking change는 core와 Flutter 앱 반영을 같은 branch에서 조율한다. legacy web은 제거 전 필요한 경우에만 함께 조율한다.
- schema가 추가되면 sample payload나 compatibility note를 함께 둔다.
- generated client가 생기면 생성 명령과 source schema를 문서화한다.
## 다른 도메인과의 경계
- **core**: contracts는 API shape의 source-of-truth이고 core는 이를 구현한다.
- **web**: web은 contracts를 소비하거나 generated client를 감싼다.
- **mobile**: mobile은 contracts를 소비하되 platform behavior는 mobile 도메인에서 다룬다.
- **web**: legacy web은 제거 전 필요한 경우에만 contracts를 소비하거나 generated client를 감싼다.
- **workspace-ops**: contracts 생성/검증 명령이 root script가 되면 workspace-ops와 함께 갱신한다.
## 금지 사항

View file

@ -30,8 +30,8 @@ NomadCode의 백엔드 오케스트레이션 도메인이다. workflow, scheduli
## 제외 경로
- `apps/web/` — backend API를 사용하는 웹 UI이며 core 구현을 직접 소유하지 않는다.
- `apps/mobile/` — 모바일/데스크톱 클라이언트이며 core 내부 패키지를 직접 참조하지 않는다.
- `apps/mobile/` — Flutter-first 제품 클라이언트이며 core 내부 패키지를 직접 참조하지 않는다.
- `apps/web/` — 이전 React/Vite scaffold이며 core 구현을 직접 소유하지 않는다.
- `packages/contracts/` — 공유 API/schema 계약의 소유 영역이다.
## 주요 구성 요소
@ -71,15 +71,15 @@ NomadCode의 백엔드 오케스트레이션 도메인이다. workflow, scheduli
- 외부 서비스 호출은 `internal/adapters/<provider>` 아래에 격리한다.
- 환경 변수 기본값과 alias는 `internal/config`에서 관리하고 README의 실행 예시와 어긋나지 않게 유지한다.
- scheduler 변경은 가능한 한 job 단위 테스트를 추가한다.
- HTTP API 변경은 web/mobile 영향과 contracts 반영 필요성을 함께 판단한다.
- HTTP API 변경은 Flutter 앱 영향과 contracts 반영 필요성을 함께 판단한다. legacy web 영향은 제거 전 필요한 경우에만 확인한다.
- Plane 관련 작업에서는 board state와 agent 내부 실행 상태를 같은 workflow state로 섞지 않는다. `testing`은 agent가 자체 검증과 리뷰 루프를 끝낸 뒤 사용자 테스트를 기다리는 상태로 사용한다.
- Plane/Jira work item 본문(description)은 작업 요구사항과 맥락의 원본으로 취급하고, agent 실행 상태를 매번 갱신하는 저장소로 사용하지 않는다.
## 다른 도메인과의 경계
- **contracts**: API shape가 클라이언트와 공유되면 contracts에 먼저 표현하거나 문서화한다.
- **web**: web은 HTTP/API client를 통해 core와 통신한다. core 내부 Go package를 전제하지 않는다.
- **mobile**: mobile은 public API와 notification/auth 계약만 의존한다.
- **web**: legacy web은 제거 전 필요한 경우에만 HTTP/API client를 통해 core와 통신한다. core 내부 Go package를 전제하지 않는다.
- **workspace-ops**: root helper 변경은 workspace-ops 소유이고, core-local bin 변경만 core 소유다.
## 금지 사항

View file

@ -8,7 +8,7 @@ last_rule_updated_at: 2026-05-21
## 목적 / 책임
NomadCode의 Flutter 모바일/데스크톱 클라이언트 도메인이다. 앱 entrypoint, Mattermost auth, push notification, platform integration을 담당한다.
NomadCode의 Flutter-first 제품 UI 도메인이다. 모바일/데스크톱/선택적 web target의 기준 클라이언트, 앱 entrypoint, Mattermost auth, push notification, platform integration을 담당한다.
## 포함 경로
@ -22,7 +22,7 @@ NomadCode의 Flutter 모바일/데스크톱 클라이언트 도메인이다. 앱
## 제외 경로
- `services/core/` — backend orchestration/API implementation.
- `apps/web/`browser console implementation.
- `apps/web/`이전 React/Vite browser console scaffold.
- `packages/contracts/` — shared API/schema contracts.
## 주요 구성 요소
@ -42,6 +42,7 @@ NomadCode의 Flutter 모바일/데스크톱 클라이언트 도메인이다. 앱
- Firebase Messaging 변경은 foreground, background, permission flow를 함께 검토한다.
- Android native push 변경은 Kotlin/Java receiver/service, manifest, Dart bridge 영향을 함께 확인한다.
- public API 호출을 추가하면 contracts/core 영향 여부를 확인한다.
- project/task/agent/workspace 제품 UI는 Flutter 앱을 기준 구현으로 둔다.
- `flutter test`를 기본 검증으로 사용한다.
- 현재 baseline의 `avoid_print` info는 별도 cleanup 작업으로 다루고, 기능 변경과 섞지 않는다.
@ -49,7 +50,7 @@ NomadCode의 Flutter 모바일/데스크톱 클라이언트 도메인이다. 앱
- **core**: mobile은 core API/notification 계약에 의존하되 core 내부 구현을 알지 않는다.
- **contracts**: mobile이 사용하는 API/event shape는 contracts 후보로 올린다.
- **web**: 사용자 경험 방향은 맞출 수 있지만 UI 구현은 공유하지 않는다.
- **web**: React/Vite web은 legacy scaffold이며 Flutter 제품 UI를 복제하지 않는다.
- **workspace-ops**: root scripts와 agent rules는 mobile 내부에 복제하지 않는다.
## 금지 사항

View file

@ -8,7 +8,7 @@ last_rule_updated_at: 2026-05-21
## 목적 / 책임
NomadCode의 브라우저 운영 콘솔 도메인이다. 프로젝트/agent workspace, backend integration, UI shell, 클라이언트 상태 관리를 담당한다.
NomadCode의 이전 React/Vite 브라우저 운영 콘솔 scaffold 도메인이다. Flutter-first 전환 이후 장기 제품 UI 경로에서는 제외하며, 이 도메인의 작업은 제거, 격리, 또는 legacy 상태 보존에 한정한다.
## 포함 경로
@ -25,7 +25,7 @@ NomadCode의 브라우저 운영 콘솔 도메인이다. 프로젝트/agent work
## 제외 경로
- `services/core/` — API implementation과 persistence는 core 도메인이다.
- `apps/mobile/` — Flutter UI는 mobile 도메인이다.
- `apps/mobile/` — Flutter 제품 UI source of truth는 mobile 도메인이다.
- `packages/contracts/` — shared schema/source-of-truth는 contracts 도메인이다.
## 주요 구성 요소
@ -45,23 +45,22 @@ NomadCode의 브라우저 운영 콘솔 도메인이다. 프로젝트/agent work
## 유지할 패턴
- 페이지는 `src/routes`, layout은 `src/layout`, 재사용 UI는 `src/components`에 둔다.
- API 호출 형태가 바뀌면 `src/api`를 먼저 갱신하고, 필요 시 contracts/core 변경을 같은 작업에 포함한다.
- shell/navigation 변경은 모바일 viewport도 함께 고려한다.
- 새 UI 상태는 route-local state와 shared store 중 책임 범위를 먼저 판단한다.
- settings/integration UI는 실제 API 연결 여부와 placeholder 동작을 구분한다.
- `npm run check`가 통과하도록 TypeScript type을 유지한다.
- 새 제품 기능을 React web에 추가하지 않는다.
- 제거 전 legacy 유지가 필요한 경우 기존 `src/routes`, `src/layout`, `src/components`, `src/api`, `src/stores` 구조를 유지한다.
- API 호출 형태가 바뀌면 Flutter 앱과 contracts/core 경계를 우선 확인하고, legacy web 변경은 필요한 최소 범위로 제한한다.
- legacy scaffold를 직접 수정할 때는 `npm run check`가 통과하도록 TypeScript type을 유지한다.
## 다른 도메인과의 경계
- **core**: web은 core의 HTTP/API surface만 사용한다.
- **contracts**: 반복되는 request/response shape는 contracts 후보로 올린다.
- **mobile**: UX 개념은 공유할 수 있지만 Flutter 구현과 React 구현은 분리한다.
- **mobile**: Flutter 앱이 제품 UI source of truth이며, web은 제품 UI 구현을 복제하지 않는다.
- **workspace-ops**: root `bin/*`나 monorepo 문서는 web 변경과 분리한다.
## 금지 사항
- core 내부 구조를 web 컴포넌트에 하드코딩하지 않는다.
- 새 제품 화면을 React web에 추가하지 않는다.
- API mock과 실제 API shape를 장기간 다르게 유지하지 않는다.
- 공통 UI component에 page-specific side effect를 넣지 않는다.
- 대규모 visual/style 변경과 API behavior 변경을 한 커밋에 섞지 않는다.

View file

@ -7,13 +7,13 @@
## 프로젝트 개요
NomadCode는 AI 병렬 작업 운용을 위한 원레포다. 백엔드 오케스트레이션, 웹 콘솔, Flutter 앱, 공유 계약, 작업 운영 스크립트를 하나의 작업 흐름으로 묶는다.
NomadCode는 AI 병렬 작업 운용을 위한 원레포다. 백엔드 오케스트레이션, Flutter 앱, 공유 계약, 작업 운영 스크립트를 하나의 작업 흐름으로 묶는다.
## 주요 구조
- `services/core/` — Go 기반 백엔드, workflow, scheduler, persistence, 외부 adapter.
- `apps/web/` — React/Vite 기반 운영 콘솔과 agent/project workspace UI.
- `apps/mobile/` — Flutter 기반 모바일/데스크톱 클라이언트와 알림 연동.
- `apps/mobile/` — Flutter 기반 제품 UI source of truth, 모바일/데스크톱 클라이언트와 알림 연동.
- `apps/web/` — 이전 React/Vite 운영 콘솔 scaffold. Flutter-first 전환에서 제거 또는 격리 대상.
- `packages/contracts/` — 서비스와 클라이언트가 공유하는 API/schema 계약.
- `bin/` — 원레포 공통 test/build/lint/dev entrypoint.
- `docs/` — 아키텍처와 운영 문서.
@ -22,7 +22,6 @@ NomadCode는 AI 병렬 작업 운용을 위한 원레포다. 백엔드 오케스
## 기술 스택
- Backend: Go, chi, pgx, River, SQLC, PostgreSQL.
- Web: TypeScript, React, Vite, TanStack Router, TanStack Query, Zustand.
- Mobile: Flutter/Dart, Firebase Messaging, local notifications, HTTP.
- Workspace: shell scripts under `bin/`, Git subtree-imported history.
@ -31,7 +30,7 @@ NomadCode는 AI 병렬 작업 운용을 위한 원레포다. 백엔드 오케스
- 원레포 루트에서 가능한 작업은 `bin/test`, `bin/lint`, `bin/build`, `bin/dev`를 우선 사용한다.
- cross-boundary 변경은 계약, 서비스, 클라이언트 반영을 같은 브랜치에서 닫는다.
- `services/core` 변경은 `go test ./...` 또는 `bin/test`로 확인한다.
- `apps/web` 변경은 `npm run check` 또는 `npm run verify`로 확인한다.
- `apps/web`는 장기 제품 UI 경로에서 제외한다. 제거 전 legacy scaffold를 직접 변경할 때만 `npm run check` 또는 `npm run verify`로 확인한다.
- `apps/mobile` 변경은 `flutter test`와 필요 시 `flutter analyze --no-fatal-infos`로 확인한다.
- `packages/contracts`가 실제 계약을 갖기 전에는 API 형태를 서비스/클라이언트에 중복 고정하지 말고 계약 후보를 문서화한다.
- 하위 앱/서비스에 별도 `agent-ops`나 AI entry 파일을 만들지 않는다. 루트 `agent-ops`와 루트 entry 파일만 사용한다.

View file

@ -11,14 +11,6 @@ if [ -f "$root/services/core/go.mod" ]; then
fi
fi
if [ -f "$root/apps/web/package.json" ]; then
if command -v npm >/dev/null 2>&1; then
(cd "$root/apps/web" && npm run build)
else
echo "skip apps/web: npm not found"
fi
fi
if [ -f "$root/apps/mobile/pubspec.yaml" ]; then
if command -v flutter >/dev/null 2>&1; then
(cd "$root/apps/mobile" && flutter build web)

View file

@ -7,8 +7,7 @@ cat <<EOF
NomadCode development entrypoints:
core: cd "$root/services/core" && bin/run
web: cd "$root/apps/web" && npm run dev
mobile: cd "$root/apps/mobile" && flutter run
app: cd "$root/apps/mobile" && flutter run
Start the services you need in separate terminals.
EOF

View file

@ -11,14 +11,6 @@ if [ -f "$root/services/core/go.mod" ]; then
fi
fi
if [ -f "$root/apps/web/package.json" ]; then
if command -v npm >/dev/null 2>&1; then
(cd "$root/apps/web" && npm run lint --if-present)
else
echo "skip apps/web: npm not found"
fi
fi
if [ -f "$root/apps/mobile/pubspec.yaml" ]; then
if command -v flutter >/dev/null 2>&1; then
(cd "$root/apps/mobile" && flutter analyze --no-fatal-infos)

View file

@ -11,21 +11,6 @@ if [ -f "$root/services/core/go.mod" ]; then
fi
fi
if [ -f "$root/apps/web/package.json" ]; then
if command -v npm >/dev/null 2>&1; then
(
cd "$root/apps/web"
if node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)" >/dev/null 2>&1; then
npm test -- --run
else
npm run check --if-present
fi
)
else
echo "skip apps/web: npm not found"
fi
fi
if [ -f "$root/apps/mobile/pubspec.yaml" ]; then
if command -v flutter >/dev/null 2>&1; then
(cd "$root/apps/mobile" && flutter test)

View file

@ -3,8 +3,8 @@
The workspace is organized by runtime boundary rather than by task.
- `services/core` owns orchestration, persistence, scheduling, and external model/service adapters.
- `apps/web` owns the operator console and browser-based agent workspace.
- `apps/mobile` owns the mobile and desktop Flutter surfaces.
- `apps/mobile` owns the Flutter-first product UI across mobile, desktop, and optional web targets.
- `apps/web` is the previous React/Vite console scaffold and is slated for removal or isolation from the product path.
- `packages/contracts` owns schemas shared across clients and services.
- `agent-ops` owns root agent routing, domain rules, and repeatable task workflows.