<a id="tool-catalog-reference"></a>
# 도구 이름·노출 조건 전수표

이 페이지는 고정 source revision에서 코드로 정의된 tool 이름을 전수로 고정한다. DB binding, agent flag, runtime setting, MCP 연결 결과에 따라 한 session에 실제 보이는 집합은 달라진다. 따라서 **등록 가능한 고정 이름**과 **현재 session의 노출 결과**를 구분해야 한다. 조립·승인 순서는 [도구 policy](../modules/tool-policy.md#tool-policy)를 본다.

| 고정 집합 | 이름 수 | 분모 규칙 |
|---|---:|---|
| ARTEX domain catalog | 25 | `BuiltinToolSeeds()`와 `AllDomainTools()`의 이름 합집합 |
| ARTEX host tool | 26 | orchestration 14 + platform 7 + finding retest 2 + traffic 3 |
| ARTEX 고정 이름 합계 | 51 | 위 두 집합은 이름이 겹치지 않음 |
| Norma `v0.4.3`에서 ARTEX가 노출할 수 있는 고정 이름 | 24 | core/optional/session/deferred/Skill helper; `AskUserQuestion` 제외 |
| MCP·custom callable 이름 | 가변 | DB와 원격 `tools/list` 결과이므로 고정 분모에 넣지 않음 |

[domain constructors](evidence:domain-tool-catalog) [host assembly](evidence:host-tools-orchestration) [Norma registry](evidence:norma-default-tools)

<a id="domain-tools"></a>
## ARTEX domain catalog: 25개

| 기능 | exact name | handler 효과 |
|---|---|---|
| graph·finding·fact 읽기 | `graph_overview`, `list_findings`, `list_facts`, `node_detail`, `expand_digest` | 현재 exploration의 graph, finding, fact, node, cold digest를 읽음 |
| worker 결과 재사용 | `get_worker_output`, `get_worker_trace`, `search_all_worker_traces` | 완료 결과 또는 step trace를 현재 task와 source task 범위에서 조회 |
| 계획·사람 제어 | `add_hint`, `add_intent`, `steer_work`, `set_goals`, `set_constraints` | hint/intent/goal/constraint를 쓰거나 실행 중 work에 steering message 전달 |
| 목표·work 판정 | `list_goals`, `prove_goal`, `goal_met`, `kill_work` | 목표를 읽고 증명·전체 완료 처리하거나 work를 종료 |
| asset·scope | `insert_assets`, `add_company_scope`, `list_assets`, `add_task_scope`, `list_untested_assets`, `list_companies` | asset/company/task scope를 조회·기록하고 coverage gap을 계산 |
| 결과 기록 | `report_finding`, `record_fact` | finding/evidence workflow 또는 exploration fact에 writeback |

`list_worker_traces`는 `ToolSet` 내부 helper와 cross-task wrapper 구현에 쓰이지만 위 세 역할 목록과 `AllDomainTools()`에는 없다. 직접 노출되는 ARTEX domain name으로 세면 25개이며, 대응 host wrapper는 `list_task_worker_traces`다. Coverage를 끄면 mainagent/planner 후보에서 `list_untested_assets`만 빠진다. `add_task_scope`는 task 범위 경계에도 쓰이므로 남는다. [domain tools](evidence:domain-tool-catalog)

<a id="domain-role-bindings"></a>
### 역할별 code 후보와 fresh-DB 기본 binding

| 역할 | code 후보 | fresh DB에서 기본 노출되는 domain tool |
|---|---:|---|
| `mainagent` | 20 | `graph_overview`, `list_findings`, `list_facts`, `node_detail`, `expand_digest`, `get_worker_output`, `get_worker_trace`, `search_all_worker_traces`, `add_hint`, `add_intent`, `steer_work`, `set_goals`, `set_constraints`, `insert_assets`, `add_company_scope`, `list_assets`, `report_finding`, `record_fact`, `add_task_scope`, `list_untested_assets` |
| `planner` | 20 | 후보는 `graph_overview`, `list_findings`, `list_facts`, `node_detail`, `expand_digest`, `get_worker_output`, `get_worker_trace`, `search_all_worker_traces`, `list_goals`, `add_intent`, `prove_goal`, `goal_met`, `kill_work`, `steer_work`, `report_finding`, `list_companies`, `list_assets`, `add_company_scope`, `add_task_scope`, `list_untested_assets`; 이 중 `goal_met`은 기본 unbound라 fresh DB 실효 기본은 19개 |
| `worker` | 8 | `list_findings`, `report_finding`, `record_fact`, `insert_assets`, `list_assets`, `search_all_worker_traces`, `get_worker_trace`, `node_detail` |
| `goals` | 2 catalog seed | `set_goals`, `set_constraints`; 실제 one-shot run은 이 둘을 직접 만들고 real asset store와 task id가 있으면 `add_task_scope`도 코드에서 직접 더함 |
| `auto` | 5 | `report_finding`, `insert_assets`, `add_company_scope`, `list_assets`, `list_companies` |
| `pentest` | 5 | `list_assets`, `insert_assets`, `report_finding`, `list_findings`, `list_companies` |

표는 새 DB의 seed와 one-shot 보정을 모두 마친 뒤의 기본값이다. 단, goals one-shot은 `AugmentTools`/`ToolResolve`를 거치지 않으므로 catalog의 goals binding·description/schema override가 이 실행 경로에는 적용되지 않는다. `tools.agents`, `enabled`, description/schema/default는 운영자가 바꿀 수 있고 first-insert seed는 이후 편집을 덮지 않는다. Task-less custom/auto agent에 catalog로 graph tool을 추가하면 server-level registry가 handler를 주입하지만 exploration store가 없어 호출이 명시적으로 실패할 수 있다. [catalog seed](evidence:tool-catalog) [server wiring](evidence:assembly-server)

<a id="host-tools"></a>
## ARTEX host tool: 26개

| 계열 | 수 | exact name | 생성·기본 노출 조건 |
|---|---:|---|---|
| cross-task orchestration | 14 | `list_tasks`, `list_llm_profiles`, `spawn_task`, `pause_task`, `get_task_graph`, `list_task_findings`, `add_task_hint`, `get_task_worker_trace`, `list_task_worker_traces`, `search_task_worker_traces`, `get_task_node_detail`, `update_finding_report`, `get_finding_traffic`, `bind_finding_traffic` | 항상 handler를 조립하고 DB catalog가 binding/enabled를 적용. one-shot default 보정 뒤 14개 모두 `auto`; `bind_finding_traffic`는 `reporter`에도 남음 |
| platform mutation | 7 | `create_skill`, `update_skill_file`, `create_custom_tool`, `update_custom_tool`, `create_mcp`, `update_mcp`, `delete_assets_by_host` | 항상 handler를 조립하며 fresh DB 기본은 `auto` |
| finding retest | 2 | `get_finding_retest_context`, `record_finding_retest_result` | seeded editable `finding-retester` agent에 기본 binding; conversation context가 finding을 고정 |
| traffic store | 3 | `traffic_search`, `traffic_get`, `traffic_blob` | capture가 켜지고 recorder가 실제 존재할 때만 handler 조립; fresh DB 기본은 `worker` |

Reporter one-shot seed는 `update_finding_report`, `get_task_node_detail`, `list_task_findings`, `get_task_worker_trace`, `list_task_worker_traces`, `search_task_worker_traces`, `get_task_graph`를 추가하고 evidence 보정은 `get_finding_traffic`를 더한다. 기존 DB 또는 사용자가 편집한 DB의 binding은 이 표와 다를 수 있다. `pgResetTool`은 orchestration/platform tool을 `auto` 하나로 되돌리므로 `bind_finding_traffic`를 reset하면 초기 reporter binding도 사라지는 것이 현재 구현이다. [orchestration](evidence:host-tools-orchestration) [platform](evidence:host-tools-platform) [retest](evidence:host-tools-retest) [traffic](evidence:host-tools-traffic)

<a id="norma-tools"></a>
## Norma 고정 이름: 24개

| 계열 | 수 | exact name | ARTEX에서의 조건 |
|---|---:|---|---|
| `DefaultTools()` | 9 | `Read`, `Write`, `Edit`, `MultiEdit`, `LS`, `Glob`, `Grep`, `Bash`, `sleep` | mainagent/planner/chat 계열 base. worker는 `MultiEdit`, `Glob`, `Grep`를 빼고 6개 사용 |
| network/planning option | 2 | `WebFetch`, `TodoWrite` | mainagent/planner/worker/chat options가 활성화; provider별 web search와 별도 |
| background process | 4 | `TaskOutput`, `TaskStop`, `TaskList`, `Monitor` | SDK가 기본 주입. `AGENT_CORE_DISABLE_BACKGROUND_TASKS` 또는 session option으로 비활성; goals run은 명시적으로 비활성 |
| web search | 1 | `web_search` | agent flag와 `web_search_enabled`, backend credential/config가 모두 허용할 때 주입 |
| interactive shell | 5 | `shell_open`, `shell_send`, `shell_read`, `shell_close`, `shell_list` | agent의 `interactive_shell`이 true이고 `AGENT_CORE_DISABLE_INTERACTIVE_SHELL`이 false일 때 `ToolResolve`가 주입 |
| deferred helper | 2 | `SearchExtraTools`, `ExecuteExtraTool` | 해당 agent의 deferred MCP/custom name이 하나 이상일 때 SDK가 주입 |
| Skill meta-tool | 1 | `Skill` | visible Skill registry가 비어 있지 않을 때 주입 |

Norma에는 `AskUserQuestion`도 있지만 ARTEX는 `Options.AskUser` callback을 설정하지 않으므로 ARTEX 노출 가능 24개 분모에서는 제외한다. Background tool을 끄면 Bash의 background 실행도 함께 꺼진다. [Norma options](evidence:norma-default-tools) [runtime gates](runtime-settings.md#dependency-env)

<a id="grep-bootstrap"></a>
### `Grep`의 최초 ripgrep 설치 효과

`Grep`는 `ReadOnly=true`, concurrent-safe, `allowReadOnly` permission으로 등록된다. 하지만 process에서 처음 실행할 때 PATH에 `rg`가 없고 `NORMA_DISABLE_RIPGREP`와 `NORMA_RIPGREP_NO_INSTALL`도 비어 있으며 `npm`은 있으면 다음 숨은 bootstrap을 수행한다. [Norma ripgrep resolver](evidence:norma-runtime-env)

1. `npm install -g @vscode/ripgrep`를 version pin 없이 ARTEX process identity로 실행한다.
2. 설치 뒤 PATH의 `rg`를 다시 찾고, 없으면 `npm root -g` 아래 `@vscode/ripgrep/bin/rg` 또는 `rg.exe`를 찾는다.
3. npm 부재, network/registry 오류, global-prefix 쓰기 권한 부족, binary 미발견, 이후 `rg` 실행 오류는 모두 pure-Go 구현으로 fallback한다.

Resolution은 process-wide `sync.Once`라 성공·실패 결과를 다음 호출에 고정한다. 설치 command의 stdout/stderr와 실패 원인은 tool result에 노출하지 않으며, fallback이면 검색 자체는 계속된다. 따라서 tool metadata가 주장하는 read-only/self-allow 효과와 실제 첫 호출의 network 및 global filesystem mutation이 맞지 않는다. ARTEX intercept가 `Grep`를 대상으로 삼더라도 Norma의 read-only metadata와 설치 subcommand는 별도 tool call/trace로 나타나지 않는다. 운영 제어는 [Grep bootstrap 운용](../operations.md#grep-bootstrap-operations)을 본다.

<a id="dynamic-tools"></a>
## 동적 MCP·Skill·custom tool

### MCP

Enabled MCP server의 원격 `tools/list` 결과는 `mcp__<server>__<tool>`이라는 ARTEX-visible name으로 등록된다. Agent에 직접 visible이고 visible Skill의 `mcps`에 속하지 않은 server는 session 시작부터 호출 가능하다. Visible Skill이 server를 선언하면 direct visibility도 우선하지 못하고 Skill 호출 뒤 unlock되며, resume은 이전 `Skill` call history에서 unlock set을 복구한다. 원격 server가 내놓는 이름과 개수는 실행 시점 값이라 고정 완전성 분모가 없다. [MCP assembly](evidence:assembly-server) [deferred flow](evidence:deferred)

| shipped seed | transport·실행 | 기본 상태 |
|---|---|---|
| `browser` | stdio, `npx ["@playwright/mcp","--headless"]` | disabled, env `{}` |
| `ScopeSentry` | HTTP placeholder, URL 없음, header `X-API-Key` empty | disabled |

### Skill

Shipped directory는 `api-recon`, `playwright-cli`, `scopesentry` 3개다. Fresh DB visibility seed는 `api-recon`만 `auto`, `pentest`, `worker`에 켠다. `playwright-cli`와 `scopesentry`는 기본 invisible이다.

현재 `skills/scopesentry/SKILL.md`는 첫 `---` 뒤의 YAML head에 Markdown 본문이 섞이고 `## name:`을 사용한다. Norma parser는 malformed head의 metadata를 비우고 directory 이름 `scopesentry`를 fallback name으로 쓰며, 파일에는 `mcps:`가 없다. 따라서 `db.go` 주석과 달리 shipped source만으로 `ScopeSentry` MCP를 이 Skill에 gate하지 않는다. 이는 문서화된 동작이 아니라 source 불일치다. [shipped skills](evidence:shipped-skills)

### Custom tool kind: 4개

| `kind` | callable | 실행 계약 | 추가 조건 |
|---|---|---|---|
| `shell` | 아니오 | 설치된 CLI/environment hint를 해당 agent의 `Bash` description에 붙임 | enabled + binding; executable을 직접 등록하지 않음 |
| `command` | 예 | template을 렌더링하고 Norma `Bash` handler로 host command 실행 | name/schema/binding, timeout/output와 실제 command side effect 검토 |
| `script` | 예 | `python_interpreter`로 code를 실행하고 parameter JSON을 stdin에 전달 | interpreter가 필요하며 code/timeout/output가 DB 정의 |
| `http` | 예 | method/URL/header/body template을 ARTEX HTTP client로 요청 | non-empty object schema가 필수; redirect/response cap/target 정책 확인 |

`command`, `script`, `http` 이름은 사용자 정의이며 `deferred`일 수 있다. Deferred custom tool은 Skill gate가 아니라 global deferred여서 schema만 초기 prompt에서 숨고 `SearchExtraTools`로 발견할 수 있으며 시작부터 unlock set에는 들어간다. `shell` row는 callable 도구 수에 포함하지 않는다. [custom execution](evidence:custom-tools)

<a id="tool-count-boundary"></a>
## 완전성 판정 경계

- 고정 source 이름 완전성은 ARTEX 51개와 Norma 24개를 각각 센다. 합계 75는 이름 inventory 합일 뿐 한 session의 tool 수가 아니다.
- Agent별 실제 노출은 code base, DB catalog/binding, coverage·capture·search·shell setting, visible Skill/MCP, remote discovery, deferred helper가 합성된 결과다.
- DB의 custom/MCP row 수와 remote `tools/list` 결과는 snapshot을 떠야만 셀 수 있다. 이를 `75/N` 같은 고정 denominator에 더하지 않는다.
- Enabled row가 있어도 handler/recorder/interpreter/remote connection/context가 없으면 호출할 수 없거나 실행 중 실패한다.
