From 1d8f16303e55cb54279f09235b26ed292116f521 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 17 Jul 2026 08:25:07 +0200 Subject: [PATCH] docs: define host workspace and MCP access --- README.md | 46 ++++++++++++++ doc/agents.md | 89 +++++++++++++++++++++++++++ doc/containers.md | 50 +++++++++++++++ doc/debug-documentation-guidelines.md | 46 ++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 doc/debug-documentation-guidelines.md diff --git a/README.md b/README.md index 8a74835..81d0f11 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,23 @@ Neovim, Termdebug, nvim-dap oraz MCP tmuxa i Neovima. Kod karty, wyniki i artefakty są bind-mountem na hoście. Kontenery nie dostają kluczy SSH, tokenów, socketu Podmana/Dockera ani całego `/dev`. +## Pierwsza instalacja + +Pierwszy klon launchera również należy do workspace. Nie uruchamiamy +`stemctl` z przypadkowego katalogu domowego ani z kontenera: + +```bash +mkdir -p ~/dev/workspace/stem/tools +git clone http://77.90.8.171:3001/edu-tools/stem-launcher.git \ + ~/dev/workspace/stem/tools/stem-launcher +cd ~/dev/workspace/stem/tools/stem-launcher +./stemctl workspace sync +``` + +Od tego momentu wszystkie komendy `stemctl`, karty i repozytoria odpowiedzi +pozostają pod `~/dev/workspace/stem`. Kontener dostaje wybraną kartę jako +`/workspace`, ale nie jest miejscem przechowywania źródeł. + ## Szybki start ```bash @@ -69,6 +86,10 @@ Domyślny układ: └── tokens/tokens.json ``` +Pierwszym repozytorium w `tools/` jest `stem-launcher`; to ono pobiera +workspace-info, źródła kart oraz repo środowiska. Pozostałe repozytoria są +zarządzane przez `stemctl`, a nie klonowane wewnątrz kontenera. + Jeżeli istnieje tylko starszy `~/dev/workspace/rv`, launcher wykrywa go bez niszczenia danych. Jawna migracja: @@ -102,6 +123,30 @@ się w wybranym kontenerze: Oddzielne wpisy klienta MCP mogą wskazywać inne nazwy instancji, więc jeden Codex obsługuje kilka kontenerów bez globalnego „ostatniego socketu”. +Klient MCP działający stale na hoście może także przełączać oba narzędzia +atomowo przez wspólny wskaźnik `current`: + +```bash +./stemctl mcp list +./stemctl mcp select rp2350-pointers-final +./stemctl mcp status +./stemctl mcp select 3aca2c1c4c7a +``` + +Selektor przyjmuje nazwę instancji, nazwę kontenera albo co najmniej 12 znaków +ID. Weryfikuje ID i label przez `podman inspect`, a także aktywnie sprawdza oba +serwery. Dopiero wtedy atomowo przełącza: + +```text +$XDG_RUNTIME_DIR/stem/mcp-selected/current/n.sock +$XDG_RUNTIME_DIR/stem/mcp-selected/current/t.sock +``` + +Wskaźniki prowadzą do katalogu zawierającego aktualny `container12`, więc +odtworzony kontener nie może przejąć socketów poprzednika. Neovim i tmux +otwierają nowe połączenie przy każdym wywołaniu narzędzia MCP, dlatego zmiana +działa bez restartowania klienta. + ## Komputer zdalny Na komputer ucznia wchodzimy wyłącznie SSH z parą kluczy. Launcher, Git, @@ -134,6 +179,7 @@ Nowe materiały powinny używać nazw kanonicznych. - [plan architektury](doc/architecture-plan.md) - [kontenery i interfejs](doc/containers.md) +- [wytyczne dokumentowania debugowania](doc/debug-documentation-guidelines.md) - [migracja nazw i workspace](doc/migration-stem-launcher.md) - [serie i karty](doc/series.md) - [tokeny Gitea](doc/tokens.md) diff --git a/doc/agents.md b/doc/agents.md index 2a103ea..4a7fdc4 100644 --- a/doc/agents.md +++ b/doc/agents.md @@ -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//stem//// +``` + +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 pane’a 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`: diff --git a/doc/containers.md b/doc/containers.md index ab142c0..6baa31d 100644 --- a/doc/containers.md +++ b/doc/containers.md @@ -195,6 +195,29 @@ re-enumeracji. Nie przekazuje całego `/dev`. Build i test offline nie wymagają artefaktu. Bez niego odmawia wykonania, chyba że użytkownik jawnie zaakceptuje istniejący firmware. Zapobiega to testowaniu starego programu. +## Źródła projektu + +Źródła kart i projektów pobiera wyłącznie `stemctl` na hoście, zawsze pod +`~/dev/workspace` danego konta Unix. Kanoniczny workspace STEM ma postać +`~/dev/workspace/stem`; nie używamy do pracy katalogów kontenera ani +przypadkowych klonów poza `~/dev/workspace`. Pierwszy klon launchera trafia do +`~/dev/workspace/stem/tools/stem-launcher` i od niego zaczyna się cały +bootstrap workspace. Typowy przepływ to: + +```bash +stemctl workspace sync +stemctl series cards fetch inf pointers +stemctl debug rp2350 inf pointers 4 +``` + +Katalog karty pozostaje na hoście, na przykład +`~/dev/workspace/stem/series/inf/pointers/`, i jest przekazywany kontenerowi +jako bind-mount `/workspace`. Nie klonujemy repozytoriów źródłowych wewnątrz +kontenera: kontenery są odtwarzalne i mogą zostać usunięte, natomiast host +zachowuje Git, zmiany ucznia, odpowiedzi i historię pracy. W obrazie lub +osobnym cache volume mogą znajdować się wyłącznie narzędzia, zależności i +odtwarzalne cache budowania. + ## Instancje i sockety MCP Stabilna nazwa logiczna: @@ -227,6 +250,33 @@ Publiczne wejścia launchera to `stemctl mcp tmux INSTANCE` oraz zweryfikowanego kontenera. Neovim MCP publikuje również stan i komendy Termdebug/nvim-dap. +Dla jednego stale działającego klienta hostowego dostępny jest również jawny, +atomowy przełącznik obu socketów: + +```bash +stemctl mcp list +stemctl mcp select INSTANCE_OR_CONTAINER_ID +stemctl mcp status +``` + +`mcp select` sprawdza registry, pełny ID i label kontenera, aktywnie testuje +serwery Neovima i tmuxa, a następnie jednym `rename(2)` przełącza symlink +`$XDG_RUNTIME_DIR/stem/mcp-selected/current`. Jeśli choć jeden serwer nie +odpowiada, poprzedni wybór pozostaje bez zmian. + +Katalog socketów jest tworzony przez launcher na hoście i bind-mountowany do +kontenera pod identyczną ścieżką. Dopiero `nvim` i `tmux` działające w +kontenerze tworzą odpowiednio `n.sock` i `t.sock`; hostowy Codex łączy się z +tym samym plikiem przez widok hosta. Sockety nie są przekazywane przez sieć ani +nie dają kontenerowi dostępu do socketu Podmana. + +Połączenia MCP mają profil `observe`, `assist` albo `full`. `full` jest +przeznaczony dla nauczyciela: może wykonywać dowolne działania dostępne w +Neovimie, tmuxie i terminalu wybranego kontenera jako konto ucznia. Profile +`observe` i `assist` muszą używać oddzielnych, ograniczonych providerów; +nie wolno udawać ograniczenia przez samą zmienną środowiskową przy providerze +udostępniającym ogólny Vimscript lub polecenia pane’a. + MCP nie jest czwartym kontenerem. Bridge jest częścią `dev-ui-base`, a hostowy resolver jest częścią `stem-launcher`. diff --git a/doc/debug-documentation-guidelines.md b/doc/debug-documentation-guidelines.md new file mode 100644 index 0000000..6a7c3bc --- /dev/null +++ b/doc/debug-documentation-guidelines.md @@ -0,0 +1,46 @@ +# Wytyczne dokumentowania debugowania + +## Cel + +Zrzut debuggera jest dowodem pomiaru, nie dekoracją. Ma pozwolić uczniowi +połączyć jedną operację w C z instrukcjami RISC-V, rejestrami, ramką stosu i +konkretnymi bajtami w RAM. + +## Kadr dowodowy + +- Używaj rzeczywistej sesji `stemctl debug` z karty, symulatora albo płytki. +- Zatrzymaj program w jednym nazwanym punkcie: breakpoint, checkpoint albo + instrukcja bezpośrednio przed obserwowaną operacją. +- Zachowaj wspólny układ: dashboard Termdebug/GDB po lewej, źródło C po + prawej, listing `.lst` pod źródłem. Listing musi być zsynchronizowany z PC. +- Pokaż tylko dane potrzebne do tezy: wywołanie w C, odpowiadającą instrukcję, + argument w rejestrze, fragment stosu albo pamięć w RAM. +- Dołącz podpis z platformą, taskiem i stanem pomiaru, na przykład „przed + pierwszym przydziałem pamięci”. + +## Oznaczenia + +- Stosuj najwyżej cztery krótkie oznaczenia numeryczne na jednym kadrze. +- Każdy numer ma odpowiadać jednemu zdaniu w podpisie lub legendzie. +- Bieżący kolor oznaczeń to czerwony: oznacza „zatrzymaj się i sprawdź”. + Paleta może później ulec zmianie, ale numeracja i podpis muszą pozostać + zrozumiałe bez koloru. +- Nie zasłaniaj kodu ani nie zmieniaj jego treści. Zachowaj surowy zrzut jako + źródło, a adnotowany obraz zapisz jako osobny plik. + +## Wstawienie do karty + +- Zasoby zapisuj w `doc/assets/`, np. + `task04-first-allocation-annotated.png`. +- W `doc/main.tex` umieść obraz blisko instrukcji, której dotyczy, oraz dodaj + zwięzły podpis wyjaśniający numery. +- Po zmianie zbuduj PDF skryptem `scripts/render_pdf.sh` i sprawdź stronę + wynikową w rozmiarze A4. +- W materiałach dla ucznia używaj słowa **RAM**, nie skrótu „SRAM”. + +## Przykład referencyjny + +Karta `inf/pointers`, Task04: `alloc_local(5)` przed pierwszym przydziałem. +Kadr pokazuje wywołanie C, `li a0,5` i `jal alloc_local`, wartość `a0=5` oraz +pusty `allocbuf`. Taki obraz dokumentuje związek źródła, ABI i pamięci bez +zastępowania go opisem narracyjnym.