docs: define host workspace and MCP access

This commit is contained in:
user
2026-07-17 08:25:07 +02:00
parent 1e1c124c9f
commit 1d8f16303e
4 changed files with 231 additions and 0 deletions
+89
View File
@@ -17,6 +17,10 @@ mieć wgląd w tę samą sesję, w której pracuje uczeń:
Dzięki temu agent widzi środowisko debugowania, a nie tylko statyczne pliki.
Punkt wejścia `stemctl` jest także projektem hostowym: pierwszy klon znajduje
się w `~/dev/workspace/stem/tools/stem-launcher`. Agent ani użytkownik nie
klonują launchera, kart lub repozytoriów odpowiedzi do kontenera.
## Aktualny fundament
`rv32i-hazard3-student-env` dostarcza źródła wspólnego modelu:
@@ -108,6 +112,91 @@ Aktualny ID uniemożliwia użycie socketu pozostałego po odtworzeniu kontenera.
`stemctl` traktuje te pliki jako szczegóły implementacyjne. Użytkownik i agent
dostają komendy wyższego poziomu.
### Kto tworzy sockety
Hostowy launcher `stem` najpierw tworzy katalog runtime i przekazuje go
Podmanowi jako bind-mount pod **tą samą bezwzględną ścieżką**. Po uruchomieniu
interfejsu debuggera procesy wewnątrz kontenera tworzą sockety:
- `tmux` tworzy `t.sock`,
- `nvim` tworzy `n.sock`.
Nie są one kopiowane ani przekazywane przez sieć: host i kontener widzą ten sam
plik Unix socket w zamontowanym katalogu. ID kontenera jest częścią ścieżki,
więc nowy kontener po `rm/start` dostaje nowy katalog i nie może przypadkiem
obsłużyć socketu poprzednika.
### Dynamiczny wybór kontenera
Stały provider MCP na hoście używa dwóch krótkich ścieżek:
```text
$XDG_RUNTIME_DIR/stem/mcp-selected/current/n.sock
$XDG_RUNTIME_DIR/stem/mcp-selected/current/t.sock
```
Polecenie `stemctl mcp select INSTANCE_OR_CONTAINER_ID` weryfikuje registry,
pełny ID i label kontenera oraz oba żywe serwery. Następnie atomowo przełącza
symlink `current` dla obu socketów. Dzięki temu kolejna operacja MCP trafia do
wybranej sesji tmuxa i Neovima bez restartowania Codexa. `stemctl mcp list`
pokazuje tylko rekordy registry, a `stemctl mcp status` potwierdza bieżący
wybór.
Wybór pozostaje jawny: samo stworzenie kontenera tworzy jego katalog socketów,
ale nie przejmuje automatycznie aktywnego MCP innej sesji.
### Wiele kont użytkowników i pomoc nauczyciela
Sockety muszą pozostać prywatne dla unixowego konta, które uruchamia
kontener, np.:
```text
/run/user/<uid-ucznia>/stem/<thread>/<instance>/<container-id>/
```
Nie montujemy ich do wspólnego `/tmp`, nie zmieniamy grup socketów tmuxa i nie
udostępniamy ich przez port sieciowy. Codex nauczyciela łączy się przez SSH na
konkretne konto ucznia; po drugiej stronie ograniczony wrapper MCP łączy się
lokalnie z jego `n.sock` i `t.sock`. Stdio SSH jest transportem MCP — socket
Unix nie opuszcza komputera ucznia.
Każdy uczeń ma własny tmux i Neovim. Można uruchomić wiele serwerów MCP dla
tej samej sesji (np. ucznia i nauczyciela), ale oba mogą równocześnie edytować
bufor lub wysyłać klawisze, więc nie ma gwarancji arbitrażu zmian.
Dostęp nauczyciela rozdzielamy na dwa klucze SSH:
- zwykły klucz nauczycielski z pełną powłoką, używany wyłącznie do świadomej,
ręcznej interwencji na koncie ucznia;
- osobny klucz automatyzacji Codexa z forced command, bez TTY, forwardingu i
powłoki, ograniczony do `nvim`, `tmux`, `status` i dozwolonych kontenerów.
Pełny klucz nauczyciela nie trafia do kontenera ani do konfiguracji MCP.
### Poziomy uprawnień MCP
Każdy wpis MCP otrzymuje jawny poziom dostępu. Poziom jest własnością klucza
SSH i wrappera po stronie konta ucznia, a nie ustawieniem przekazywanym przez
model lub klienta MCP:
| Poziom | Przeznaczenie | Dozwolone działania |
| --- | --- | --- |
| `observe` | podgląd postępów | stan nvim, lista i capture pane’ów tmuxa, logi i metadane; bez edycji i wysyłania klawiszy |
| `assist` | wspólne rozwiązywanie problemu | działania debuggera i jawnie dozwolona edycja/panele; bez ogólnego terminala oraz bez poleceń powłoki |
| `full` | interwencja nauczyciela | pełne sterowanie nvimem i tmuxem, w tym terminalem w wybranym kontenerze, jako konto ucznia |
`full` jest równoważny interaktywnej pracy na koncie ucznia w granicach
wybranego kontenera. W szczególności arbitralne `nvim-remote-expr`, `nvim-ex`
lub wysyłanie poleceń do panea tmuxa mogą uruchomić kod. Taki wpis tworzymy
wyłącznie dla nauczyciela i zapisujemy w audycie konto, instancję, container ID,
czas oraz użyty poziom.
Nie wystarczy przekazać `MCP_ACCESS_LEVEL=observe` do tego samego pełnego
serwera: niższe poziomy wymagają osobnych providerów z allowlistą narzędzi.
W przeciwnym razie użytkownik nadal mógłby użyć ogólnego Ex/Vimscriptu albo
terminala do obejścia ograniczenia. Klucz `full` może korzystać z obecnego
providera STEM, ponieważ jego możliwości są celowo pełne.
## Role profili
Profil `hazard3-sim`: