# 워크스페이스와 제품 저장소 관계

> 오케스트레이터 저장소, 설치 후 생성되는 ops 저장소, 제품 저장소, sibling checkout 모델, 단일 저장소 예외를 구분합니다.

- Repository: local/master-ops-with-local-mogui-ADE-orchestrator

- Human docs: https://grok-wiki.com/public/docs/local-master-ops-with-local-mogui-ade-orches-0ac7093355f3
- Complete Markdown: https://grok-wiki.com/public/docs/local-master-ops-with-local-mogui-ade-orches-0ac7093355f3/llms-full.txt

## Source Files

- `local-mogui-ade-orchestrator:README.md`
- `local-mogui-ade-orchestrator:docs/public/concepts.md`
- `local-mogui-ade-orchestrator:config/workspace-descriptor.example.json`
- `local-mogui-ade-orchestrator:src/master_runtime/core/workspace_descriptor.py`
- `local-master-ops:onboarding/02-workspace-facts.md`
- `local-master-ops:docs/charter/01-document-map.md`

---

---
title: "워크스페이스와 제품 저장소 관계"
description: "오케스트레이터 저장소, 설치 후 생성되는 ops 저장소, 제품 저장소, sibling checkout 모델, 단일 저장소 예외를 구분합니다."
---

`mogui-ADE-orchestrator`는 워크스페이스 런타임과 `master-ops/` 템플릿을 함께 보관하고, 설치 과정은 확인된 워크스페이스 루트 아래의 sibling Git checkout 목록을 `config/workspace-descriptor.json` 인벤토리로 고정한다. 제품 저장소는 이 인벤토리의 `role: "product"` 항목이고, 설치 후 생성되거나 재사용되는 ops 저장소는 `role: "ops"` 항목이다.

## 저장소 경계

| 구분 | 위치 | 역할 | 커밋 대상 |
| --- | --- | --- | --- |
| 오케스트레이터 저장소 | `mogui-ADE-orchestrator/` | 런타임 코드, 공개 `scripts/`, 설정 예시, `master-ops/` 템플릿을 제공한다. | 런타임과 템플릿 변경 |
| 템플릿 `master-ops/` | `mogui-ADE-orchestrator/master-ops/` | 설치 시 복사되는 운영 골격이다. `MANIFEST.json`과 `TEMPLATE-VERSION`이 템플릿 표면을 정의한다. | 템플릿 개선 |
| 설치된 ops 저장소 | 워크스페이스 루트 아래의 승인된 `{{OPS_REPO}}` | 차터, lineage, decisions, runbooks, workspace card, tracker 상태를 보관한다. | 워크스페이스 운영 기록 |
| 제품 저장소 | 워크스페이스 루트 아래의 일반 sibling checkout | 작업자가 PR, 검증, 구현 대상으로 다루는 실제 제품 코드다. | 제품 변경 |

<Note>
`{{OPS_REPO}}` 선택은 `{{WORKSPACE_ROOT}}` 선택과 별개다. ops 저장소는 제품 코드와 혼동되지 않는 작은 governance 저장소로 만들거나 기존 운영 저장소를 재사용한다.
</Note>

## 기본 파일 시스템 모델

워크스페이스 루트는 Git 상위 저장소나 submodule parent가 아니라 “여러 저장소를 묶는 일반 폴더”다. 설치 과정은 사용자가 붙여넣은 절대 경로만 검증하고, 에이전트가 주변 디렉터리를 스캔해 후보를 대신 고르지 않는다.

```text
{{WORKSPACE_ROOT}}/
  product-api/          # role: product
  product-web/          # role: product
  {{OPS_REPO}}/          # role: ops
  CLAUDE.md             # ops 저장소 workspace-card에서 배포된 세션 카드
  AGENTS.md             # ops 저장소 workspace-card에서 배포된 세션 카드
```

일반 다중 저장소 모델에서 `master_seat`는 보통 워크스페이스 루트의 folder workspace다. Orca가 이 plain folder를 “not a valid worktree folder”처럼 표시할 수 있지만, 이 런타임에서는 folder project의 정상 조건일 수 있다.

## `workspace-descriptor.json`

확인된 저장소 목록은 런타임 clone의 `config/workspace-descriptor.json`에 기록된다. 저장소는 workspace-root-relative `path`로 식별하며, 절대 경로 매칭은 `workspace_root`가 설정된 경우에만 그 루트 아래 상대 경로로 변환해 처리한다.

```json title="config/workspace-descriptor.json"
{
  "workspace_root_is_plain_folder": true,
  "workspace_root": "/absolute/path/to/workspace-root",
  "master_seat": "folder-workspace-of-workspace-root",
  "repositories": [
    {
      "name": "product-api",
      "path": "product-api",
      "remote": "https://github.com/example/product-api.git",
      "role": "product",
      "capabilities": ["pr", "dispatch-target"],
      "prohibited": ["direct-main-commit", "force-push"]
    },
    {
      "name": "workspace-ops",
      "path": "workspace-ops",
      "remote": "",
      "role": "ops",
      "capabilities": ["pr", "dispatch-target"],
      "prohibited": ["force-push"]
    }
  ]
}
```

<ParamField body="workspace_root_is_plain_folder" type="boolean" required>
항상 `true`다. `false`이면 런타임은 submodule parent 또는 non-plain workspace root로 보고 거부한다.
</ParamField>

<ParamField body="workspace_root" type="string | null">
절대 경로 매칭을 워크스페이스 루트 아래로 묶는 값이다. 없으면 절대 경로 후보는 저장소 항목과 매칭되지 않는다.
</ParamField>

<ParamField body="master_seat" type="string">
마스터 세션이 앉을 Orca seat 라벨이다. 다중 저장소는 보통 folder workspace, 단일 저장소 예외는 primary worktree를 쓴다.
</ParamField>

<ParamField body="repositories[].role" type="product | ops" required>
제품 코드 저장소와 운영 저장소를 구분한다. 다른 role 값은 유효하지 않다.
</ParamField>

<ParamField body="repositories[].prohibited" type="string[]" required>
하드 블록할 action 목록이다. 누락은 오류이며, 금지가 없다는 뜻은 owner-confirmed `[]`로만 표현한다.
</ParamField>

## 해석 순서와 실패 기본값

descriptor 소비자는 같은 우선순위로 설정을 찾는다.

1. 명시 경로 또는 환경 변수: `WORKSPACE_DESCRIPTOR`, `MOGUI_WORKSPACE_DESCRIPTOR`
2. 기본 파일: `config/workspace-descriptor.json`
3. 정직한 unconfigured 상태

`scripts/workspace-descriptor-check`는 repository path와 action을 받아 허용 여부를 반환한다.

```bash
scripts/workspace-descriptor-check \
  --path product-api \
  --action direct-main-commit \
  --json
```

| 종료 코드 | 의미 | 운영 판단 |
| --- | --- | --- |
| `0` | descriptor가 해당 action을 금지하지 않음 | 계속 진행 가능 |
| `1` | 해당 저장소에서 action이 금지됨 | 중단 |
| `2` | descriptor가 없거나 유효하지 않아 판단 불가 | fail closed |

알 수 없는 저장소는 기본적으로 금지로 취급한다. `--allow-unknown-repo`는 이 기본값을 바꾸지만, 워크스페이스 경계가 불명확한 작업에는 쓰지 않는다.

## 제품 저장소와 ops 저장소의 기본 금지

설치 단계의 기본값은 제품 저장소와 ops 저장소를 다르게 취급한다.

| role | 기본 capabilities | 기본 prohibited |
| --- | --- | --- |
| `product` | `["pr", "dispatch-target"]` | `["direct-main-commit", "force-push"]` |
| `ops` | `["pr", "dispatch-target"]` | `["force-push"]` |

제품 저장소의 직접 main commit과 force push는 기본 금지다. ops 저장소는 운영 기록을 보관하므로 force push가 기본 금지지만, 직접 커밋 금지는 제품 저장소 기본값처럼 자동 적용되지 않는다. owner가 descriptor를 확인한 뒤 instance 파일에서 조정한 값이 우선한다.

## 단일 저장소 예외

워크스페이스가 실제로 하나의 저장소 자체인 경우에만 `path: "."`를 사용한다. 이때 워크스페이스 루트와 제품 checkout이 같은 디렉터리이고, `master_seat`는 primary worktree가 된다.

```json title="단일 저장소 workspace-descriptor.json"
{
  "workspace_root_is_plain_folder": true,
  "workspace_root": "/absolute/path/to/single-repo",
  "master_seat": "primary-worktree",
  "repositories": [
    {
      "name": "single-repo",
      "path": ".",
      "remote": "",
      "role": "product",
      "capabilities": ["pr"],
      "prohibited": ["direct-main-commit"]
    }
  ]
}
```

이 예외는 “한 제품 저장소만 있다”는 이유만으로 자동 선택하지 않는다. 일반 규칙은 한 저장소만 있더라도 그 부모 폴더를 workspace root로 두는 것이다. `path: "."`는 workspace root 자체가 그 단일 저장소라는 owner-confirmed 구조에서만 쓴다.

## 워크스페이스 밖 저장소

사용자가 워크스페이스 밖의 저장소를 작업 대상으로 지정하면 기본 처리 방향은 move 또는 clone이다. 저장소가 `{{WORKSPACE_ROOT}}` 아래 sibling checkout으로 들어와야 인벤토리, Orca sidebar, 작업 측정이 같은 경계 안에서 동작한다.

외부 경로를 유지해야 하는 경우에는 일반 repository 항목처럼 암묵적으로 추가하지 않는다. 별도 external lane으로 절대 경로, 쓰기 권한, push 전 gate를 기록하고, 각 주장마다 따로 측정한다.

## 설치된 ops 저장소가 받는 파일

새 ops 저장소는 템플릿의 `MANIFEST.json`에 있는 Stage 1 skeleton을 복사해 만든다. 생성된 ops 저장소에는 `CLAUDE.md`, `AGENTS.md`, `docs/MASTER-OPERATIONS.md`, `docs/charter/`, `docs/runbooks/`, `docs/lineage/`, `workspace-card/`, `scripts/` 등이 들어간다.

템플릿 전용 파일은 설치된 ops 저장소에 남기지 않는다.

| 템플릿 전용 | 이유 |
| --- | --- |
| `TEMPLATE-VERSION` | 템플릿 stamp이며 설치된 ops는 `MANIFEST.json.template_version`으로 기록한다. |
| `CHANGELOG.md` | 템플릿 변경 이력이다. |
| `ONBOARDING.md` | 설치 라우터다. |
| `onboarding/` | 설치 절차 파일 묶음이다. |

`workspace-card/CLAUDE.md`와 `workspace-card/AGENTS.md`는 워크스페이스 루트의 세션 카드로 배포된다. ops 저장소 루트의 `CLAUDE.md` / `AGENTS.md`와는 다른 문서 쌍이다.

## 관련 pages

<CardGroup>
  <Card title="설치" href="/installation">
    설치 전 도구 측정, preflight, instance config, redaction rules를 확인합니다.
  </Card>
  <Card title="워크스페이스 Founding" href="/found-workspace">
    workspace root 선택, ops 저장소 생성, descriptor 작성, Gen-1 spawn 절차를 봅니다.
  </Card>
  <Card title="Orca 객체 모델" href="/orca-object-model">
    Project, workspace, worktree, terminal, folder workspace 라벨과 misplacement 조건을 구분합니다.
  </Card>
  <Card title="설정 참조" href="/configuration-reference">
    `workspace-descriptor.json`, `instance-runtime.json`, 환경 변수 override, fail-closed 동작을 확인합니다.
  </Card>
</CardGroup>
