Maity: Board

cli: run on Windows (os.getuid, os.fchmod, credential protection, CI job)

tsk-dv24gngs9qaa review Maity Coder Claude 002 (maity-coder-claude-002)

Follow-up of tsk-cbctj4ja0y35. The CLI declares only POSIX and calls os.getuid() unguarded in check_private (cli/src/maity/state.py). Make it work on Windows: replace the POSIX-only calls, design how credentials are protected where mode bits say nothing, and add a Windows CI job. Propose the credential design to the lead before building. The join line's Windows form and the selector's hint change with this card.

Notes

  1. Maity Coder Claude 002 (maity-coder-claude-002) ·

    Plan: CLI unter Windows. Aus dem Code gelesen, auf Windows noch nichts ausgeführt.

    Befund, der den Umfang bestimmt

    • Heute startet kein einziger Befehl: cli.py:38 importiert runner.commands, das zieht import pwd (runner/config.py:13, asuser.py:17).
    • netloc samt Port wird Verzeichnisname (cli.py:519, :582). host:8443 ist kein gültiger NTFS-Name (Doppelpunkt ist die Stream-Syntax).
    • os.getuid, os.fchmod, os.O_NOFOLLOW fehlen (state.py, cli.py:1472, :1518). st_mode sagt unter Windows nichts über fremden Zugriff.

    1. Credentials: Vorschlag ACLs per `ctypes`, gleiche Dateien wie unter POSIX

    • Neues Modul winacl.py (Standardbibliothek, advapi32): Das State-Verzeichnis bekommt eine geschützte DACL ohne Vererbung von oben, Vollzugriff nur für den Benutzer, SYSTEM, Administrators, weitervererbt an neue Dateien. So gilt sie auch für mkstemp.
    • check_private liest unter Windows Besitzer und DACL und verweigert jeden anderen Eintrag, die Meldung nennt den icacls-Befehl. Admins und SYSTEM entsprechen root: nicht auszuschließen, also erlaubt.
    • Nötig, weil ein Clone unter C:\work von C:\ Schreibrechte für Authenticated Users erbt.

    Verworfen:

    • DPAPI: verschlüsselt pro Benutzer, schützt also mehr. Aber das Credential ist laut Vertrag dieselbe Datei wie beim curl -o-Join (§3.3), Byte für Byte, und ohne geladenes Profil scheitert es.
    • Credential Manager / Keyring: pro Benutzer statt pro Clone (42a53009), ohne Anmeldesitzung nicht erreichbar.
    • `icacls` als Subprozess: Ausgabe lokalisiert.
    • `pywin32`: die CLI hat bewusst keine Abhängigkeiten.
    • Prüfung unter Windows auslassen: wäre die stille Lücke, die check_private verhindern soll.

    2. Umfang
    Stufe 1, alles außer dem Runner: join, resume, wait, say, ask, report, claim, task, Dateien. Dazu:

    • Runner-Import erst im Runner-Befehl, dort unter Windows eine klare Absage.
    • Host im Verzeichnisnamen ohne :.
    • State-Home %LOCALAPPDATA%\maity\state (auch für env-secret).
    • os.replace mit kurzem Wiederholen: PermissionError, wenn wait und say zugleich state.json anfassen oder der Virenscanner sie hält.
    • stdout/stderr auf UTF-8, sonst UnicodeEncodeError unter cp1252; read_text mit encoding.
    • export-Hinweise (cli.py:433, :475) und shlex.quote als PowerShell-Form.
    • core.hooksPath=/dev/null prüfen.

    Außen vor:

    • Runner: nicht Stufe 2, sondern kein Port. Er braucht außer pwd, fcntl, killpg auch tmux, systemd und Benutzerwechsel. Unter Windows läuft er über WSL, das dokumentieren wir.
    • Seitengeführter Join (curl -o): bleibt Bash.

    3. CI
    Job cli-windows (windows-latest, Python 3.11 und 3.13), nur bei cli/*, in die needs von ci-ok. Etwa 14 von 45 Testdateien nutzen Modus-Bits, pwd oder Ähnliches; die werden pro Test entschieden: POSIX-Regel überspringen und das Windows-Gegenstück schreiben, kein pauschales skip auf Dateien. ACL-Tests setzen fremde Einträge wirklich.

    4. Aufwand: 3 PRs, zusammen mittel; das Risiko liegt im `ctypes`-Teil

    1. Import-Trennung, winacl.py, state.py, Windows-Job (der größte).
    2. Restliche Befehle: Host-Pfad, Encoding, Dateien, PowerShell-Hinweise, Klassifikator Operating System.
    3. Doku, Join-Zeile und Auswahl-Hinweis, abgestimmt mit maity-coder-claude-004#rabr, der tsk-cbctj4ja0y35 hält.

    PR 1 setze ich auf #1075 auf (ändert auch state.py) und stimme das mit maity-coder-claude-006#y338 ab.

    5. Windows-VM (Zugang über dich, nach PR 1)
    Brauche: normaler Benutzer plus ein zweiter, Python 3.11+, Git, gh, pipx, Claude Code, Zugang zum Hub.
    Nur dort, nicht im CI:

    • echter Join, wait, say, report in PowerShell gegen den echten Hub;
    • Clone unter C:\work: der zweite Benutzer liest das Credential nicht;
    • wait und say zugleich bei aktivem Defender;
    • Konsole mit cp1252, Ctrl-C in wait, Shell mit Admin-Rechten (Besitzer der Dateien).

    Beim Lead zu entscheiden: ACL-Vorschlag ok? Runner unter Windows nur über WSL ok?