Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions .claude/hooks/dry-run-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,34 @@ case "$TOOL_NAME" in
;;
esac

# === MCP-write whitelist (точные совпадения tool_name) ===
# === MCP-write: IWE Gateway tools (namespace-agnostic action match) ===
# Префикс MCP-инструмента дрейфует между способами подключения к одному Gateway
# (server "iwe-knowledge", mcp.aisystant.com/mcp):
# mcp__claude_ai_IWE__<action> — legacy connector с именем "IWE"
# mcp__iwe_knowledge_<action> — OMP runtime (одинарный разделитель "_")
# mcp__iwe-knowledge__<action> — project .mcp.json (server id "iwe-knowledge")
# mcp__claude_ai_https_..._mcp__<action> — connector с именем из URL
# Exact-list по префиксу устаревает при каждой миграции namespace и пропускает
# write-инструменты (bug: gate не блокировал mcp__iwe-knowledge__personal_write и др.).
# Решение: сверять ДЕЙСТВИЕ (суффикс после последнего разделителя), а не полное имя.
# Паттерн "*_<action>" ловит и "__<action>" (двойной разделитель), и "_<action>" (OMP).
if [[ "$TOOL_NAME" == mcp__* ]]; then
for action in \
personal_write personal_delete personal_create_pack personal_propose_capture \
personal_reindex_source personal_scaffold_notes personal_connect_source \
personal_disconnect_source personal_purge_source personal_generate_fault_remind \
dt_write_digital_twin create_repository github_connect github_disconnect \
knowledge_feedback knowledge_reindex_source send_telegram_message \
run_strategist run_extractor capture_trace grant_consent \
agent_status_update request_equipment_upgrade; do
if [[ "$TOOL_NAME" == *"_${action}" ]]; then
block "$TOOL_NAME (action: $action)"
fi
done
fi

# === MCP-write: vendor tools (exact tool_name — префиксы вендоров стабильны) ===
case "$TOOL_NAME" in
mcp__claude_ai_IWE__personal_write|\
mcp__claude_ai_IWE__personal_delete|\
mcp__claude_ai_IWE__personal_create_pack|\
mcp__claude_ai_IWE__personal_propose_capture|\
mcp__claude_ai_IWE__personal_reindex_source|\
mcp__claude_ai_IWE__personal_scaffold_notes|\
mcp__claude_ai_IWE__dt_write_digital_twin|\
mcp__claude_ai_IWE__create_repository|\
mcp__claude_ai_IWE__github_connect|\
mcp__claude_ai_IWE__github_disconnect|\
mcp__claude_ai_IWE__knowledge_feedback|\
mcp__claude_ai_Gmail__create_draft|\
mcp__claude_ai_Gmail__create_label|\
mcp__claude_ai_Gmail__label_message|\
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# IWE — Intellectual Work Environment

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-0.35.4-blue.svg)](CHANGELOG.md)
[![Version](https://img.shields.io/badge/version-0.35.5-blue.svg)](CHANGELOG.md)
[![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows%20(WSL)-lightgrey.svg)]()
[![EN sync](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/TserenTserenov/FMT-exocortex-template/en-draft/badge-data.json)](https://github.com/TserenTserenov/FMT-exocortex-template/tree/en-draft)

Expand Down
40 changes: 27 additions & 13 deletions memory/dry-run-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,36 @@ Expected: tool blocked by contract, this is rehearsal failure point
\bsed\s+-i
```

### MCP-write whitelist
### MCP-write matcher

Точное имя tool (полный список — все, что НЕ read-only):
**IWE Gateway (`iwe-knowledge`, `mcp.aisystant.com/mcp`) — сверка по ДЕЙСТВИЮ, не по префиксу.**

Префикс MCP-инструмента дрейфует между способами подключения к одному и тому же Gateway,
поэтому exact-list по полному имени устаревает при каждой миграции namespace:

| Namespace | Откуда | Пример |
|---|---|---|
| `mcp__claude_ai_IWE__<action>` | legacy connector с именем «IWE» | `mcp__claude_ai_IWE__personal_write` |
| `mcp__iwe_knowledge_<action>` | OMP runtime (одинарный разделитель `_`) | `mcp__iwe_knowledge_personal_write` |
| `mcp__iwe-knowledge__<action>` | project `.mcp.json` (server id `iwe-knowledge`) | `mcp__iwe-knowledge__personal_write` |
| `mcp__claude_ai_https_..._mcp__<action>` | connector с именем, производным от URL | `mcp__claude_ai_https_mcp_aisystant_com_mcp__personal_write` |

Хук блокирует по **действию** — суффиксу после последнего разделителя (`*_<action>` ловит и
`__<action>`, и OMP-вариант `_<action>`). Список действий (все write / side-effect):

```
personal_write personal_delete personal_create_pack personal_propose_capture
personal_reindex_source personal_scaffold_notes personal_connect_source
personal_disconnect_source personal_purge_source personal_generate_fault_remind
dt_write_digital_twin create_repository github_connect github_disconnect
knowledge_feedback knowledge_reindex_source send_telegram_message
run_strategist run_extractor capture_trace grant_consent
agent_status_update request_equipment_upgrade
```

**Vendor MCP — exact tool_name** (префиксы вендоров стабильны):

```
mcp__claude_ai_IWE__personal_write
mcp__claude_ai_IWE__personal_delete
mcp__claude_ai_IWE__personal_create_pack
mcp__claude_ai_IWE__personal_propose_capture
mcp__claude_ai_IWE__personal_reindex_source
mcp__claude_ai_IWE__personal_scaffold_notes
mcp__claude_ai_IWE__dt_write_digital_twin
mcp__claude_ai_IWE__create_repository
mcp__claude_ai_IWE__github_connect
mcp__claude_ai_IWE__github_disconnect
mcp__claude_ai_IWE__knowledge_feedback
mcp__claude_ai_Gmail__create_draft
mcp__claude_ai_Gmail__create_label
mcp__claude_ai_Gmail__label_message
Expand Down
Loading