# STEM Launcher `stemctl` jest hostowym wejściem do kart pracy, Git i trzech źródłowo budowanych kontenerów STEM. Historyczna nazwa zdalnego repo może nadal brzmieć `rv-launcher`; `rvctl` pozostaje ostrzegającym wrapperem zgodności. Launcher nie pobiera i nie publikuje gotowych obrazów środowiska. Klonuje repo narzędzi zawierające `Dockerfile` i `docker-compose.yml`, a brakujący profil buduje lokalnie rootless Podmanem. Tag `localhost/stem/...:local` jest tylko lokalnym wpisem cache runtime. ## Model | Profil | Targety | Zastosowanie | | --- | --- | --- | | `native-amd64` | `native` | C/C++, golden tests, ASan/UBSan, GDB | | `hazard3-sim` | `hazard3-baremetal`; `hazard3-freertos` po BSP timer/IRQ | RTL Hazard3/Verilator bez płytki | | `rp2350` | `rp2350-rv`, `rp2350-arm` | Pico 2/2 W, FreeRTOS, OpenOCD/picotool | W każdym profilu interfejs pozostaje taki sam: tmux z prefixem `Ctrl-s`, 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`. ## Szybki start ```bash ./stemctl workspace sync ./stemctl series list ./stemctl series cards fetch inf bss ./stemctl test native-amd64 inf bss 1 ./stemctl test hazard3-sim inf bss 1 ./stemctl debug hazard3-sim inf bss 1 ./stemctl probe list ./stemctl deploy rp2350 inf bss 1 \ --target rp2350-rv --device /dev/bus/usb/001/006 ``` Pierwsze wywołanie danego profilu może potrwać, ponieważ buduje go ze źródłowego Dockerfile. Kolejne korzystają z lokalnych warstw cache. Wymuszenie samego przygotowania środowiska: ```bash ./stemctl env sync ./stemctl env build native-amd64 ./stemctl env build hazard3-sim ./stemctl env build rp2350 ``` `env sync` klonuje lub aktualizuje `edu-tools/rv32i-hazard3-student-env`. Repo środowiska zawiera źródłowy Dockerfile i pliki Compose. ## Workspace Domyślny układ: ```text ~/dev/workspace/stem/ ├── meta/workspace-info/ ├── series/// ├── tools/ │ ├── stem-launcher/ │ └── rv32i-hazard3-student-env/ └── tokens/tokens.json ``` Jeżeli istnieje tylko starszy `~/dev/workspace/rv`, launcher wykrywa go bez niszczenia danych. Jawna migracja: ```bash ./stemctl workspace migrate ./stemctl workspace doctor ``` ## Akcje i tożsamość instancji Jedna logiczna instancja zachowuje nazwę między `build`, `test`, `run`, `debug` i `attach`. Bieżący ID kontenera wchodzi natomiast do krótkiej ścieżki socketu: ```text $XDG_RUNTIME_DIR/stem////t.sock $XDG_RUNTIME_DIR/stem////n.sock ``` Resolver wykonuje `podman inspect` przed połączeniem i odrzuca osierocony socket. Pozwala to jednemu Codexowi obsługiwać kilka kontenerów bez kolizji. Stabilne wejścia MCP wymagają jawnej instancji i uruchamiają serwer znajdujący się w wybranym kontenerze: ```bash ./stemctl mcp tmux hazard3-sim-inf-bss-t1 ./stemctl mcp nvim hazard3-sim-inf-bss-t1 ``` Oddzielne wpisy klienta MCP mogą wskazywać inne nazwy instancji, więc jeden Codex obsługuje kilka kontenerów bez globalnego „ostatniego socketu”. ## Komputer zdalny Na komputer ucznia wchodzimy wyłącznie SSH z parą kluczy. Launcher, Git, rootless Podman i sockety działają na tym komputerze: ```bash ssh uczen-lab cd ~/dev/workspace/stem/tools/stem-launcher ./stemctl status hazard3-sim --instance lekcja-1 ./stemctl debug hazard3-sim inf bss 1 --instance lekcja-1 ``` Nie kopiujemy prywatnego klucza do kontenera. Jeżeli potrzebny jest zdalny GDB/MCP, używamy jawnego tunelu SSH albo wykonujemy klienta po stronie zdalnej. ## Zgodność Aliasy nadal działają: ```text host -> native-amd64 rv32i -> hazard3-sim rvctl -> stemctl RV_* -> fallback dla STEM_* ``` Nowe materiały powinny używać nazw kanonicznych. ## Dokumentacja - [plan architektury](doc/architecture-plan.md) - [kontenery i interfejs](doc/containers.md) - [migracja nazw i workspace](doc/migration-stem-launcher.md) - [serie i karty](doc/series.md) - [tokeny Gitea](doc/tokens.md) - [przegląd Claude](doc/review-claude-2026-07-14.md)