Sari la conținut

Control remote și mobil

Control Center este o aplicație de desktop, dar munca pe care o urmărește nu se oprește când te ridici de la birou. Controlul remote îți asociază telefonul cu cc_server, folosind Remote, aplicația companion de la remote.usectrl.dev, ca să urmărești flota de acolo: să citești mesaje și tichete, să răspunzi unui agent, să triezi fluxul de știri, fără ca audio-ul, transcrierea, codul sursă sau credențialele care există pe server să îl părăsească vreodată.

Gândește-te la el ca la un companion al biroului, folosit mai ales pentru citire. Nu este menit să înlocuiască clientul complet de desktop.

Telefonul ajunge la cc_server printr-un WebSocket: fie o conexiune directă (loopback, LAN, Tailnet sau wss://), fie o cameră cu acces pe bază de invitație pe un broker de semnalizare care retransmite cadre sigilate. Nu există niciun canal de date de la egal la egal.

Telefonul asociat ajunge la o felie mică și intenționată din suprafața serverului:

  • Citește tichete, agenți, spații și mesajele lor, plus fluxul tău de știri
  • Răspunde: trimite un mesaj într-un spațiu, actualizează sau atribuie un tichet, marchează un articol ca citit sau salvat
  • Rulează un playbook: instanțiază un șablon de plan salvat, cu parametrii lui. Acest lucru doar propune un plan; nimic nu se execută și nu se cheltuie până când un operator nu îl aprobă în Plan Studio pe un client complet
  • Comută între spațiile de lucru, din selectorul propriu al telefonului

Asta este aproape tot. Un telefon este un principal cu privilegii mai reduse decât un client complet. Nu poate porni procese, nu poate cheltui buget LLM, nu poate face push pe GitHub și nu poate crea spații de lucru. Vezi modelul de acces pentru felul în care acest lucru este impus, nu doar intenționat.

Conexiunea merge pe un releu intermediat: serverul se alătură unei camere cu acces pe bază de invitație pe un broker wss://, în calitate de proprietar, iar fiecare client asociat — desktop, web, telefon — se alătură aceleiași camere cu un token de admitere cu durată limitată. Trei piese se întâlnesc aici:

Piesă Rol
Remote (aplicația de telefon) Aplicația web companion, găzduită implicit la remote.usectrl.dev sau auto-găzduită. Se încarcă într-un browser și păstrează înregistrarea de asociere în IndexedDB.
Broker de releu Un releu wss:// fără stare (cc_signaling_server) care găzduiește camere cu N căi. Transportă numai cadre opace: fiecare payload este sigilat cap la cap între telefon și server, astfel încât brokerul nu vede niciodată datele aplicației sau secretul de asociere și nu interpretează niciodată ce retransmite.
cc_server Proprietarul camerei. Răspunde apelurilor telefonului prin același dispatcher pe care îl folosesc toți ceilalți clienți.

O ofertă de asociere conține un descriptor de conexiune care enumeră fiecare cale către server (LAN, Tailnet, wss:// public, releu) plus amprenta lui de identitate. Rezolvitorul telefonului alege cea mai bună cale accesibilă și fixează amprenta la prima conectare (TOFU); releul garantează conectivitatea chiar și atunci când nu există nicio cale directă, fără a putea citi vreodată traficul.

Asocierea este emisă din aplicație și livrată ca link profund; vezi Asociază un dispozitiv pentru procedură. Aici contează anatomia.

https://<pwa-host>/#<payload>

Payload-ul călătorește în fragmentul URL-ului, partea de după # pe care browserele nu o trimit niciodată serverului, așa că gazda HTTPS a PWA nu îl vede niciodată. El conține tot ce îi trebuie telefonului ca să ajungă la server și să dovedească cine este: descriptorul de conexiune (fiecare cale plus amprenta de identitate), un ID de dispozitiv emis proaspăt, o cheie prepartajată de 32 de octeți și un marcaj de expirare. Telefonul îl decodează, stochează local o înregistrare de asociere și elimină fragmentul, astfel încât secretul părăsește URL-ul.

Există două forme de payload și ele nu sunt interschimbabile. Codul QR al telefonului, emis din panoul de asociere din aplicație, este PairingPayload v2 de mai sus, îndreptat spre gazda PWA Remote. cc_server pair --client-url emite un link v1 diferit, mai vechi ({s, i, k} — URL de server, ID de dispozitiv, cheie), destinat exclusiv clientului web.

Ele diferă și prin durata de viață, lucru ușor de greșit:

Emis de Expirarea credențialului
Panoul de asociere din aplicație (pairing.mint) 30 de zile, întotdeauna
cc_server pair din linia de comandă Niciuna — credențialul nu expiră

Un dispozitiv asociat este autentificat, dar nu de încredere. Mai multe porți independente împiedică o asociere aprobată (sau scursă) să devină control deplin asupra serverului.

O cheie de asociere validă dovedește ce dispozitiv ești. Ce poți citi sau modifica este decis de rolul tău în spațiul de lucru, re-rezolvat la fiecare apel în parte, și de acordările per repo pentru orice expune conținut de repo. Un dispozitiv care deține o cheie perfect validă, dar aparține unui utilizator care nu este membru al spațiului de lucru numit, este refuzat cu “Not a member of this workspace”.

Pragul de rol este derivat din tipul operațiunii, cu excepția cazului în care aceasta își declară propriul prag: citirile necesită guest, mutațiile necesită member, operațiunile distructive necesită admin.

Dincolo de verificarea rolului, o sesiune de telefon are o capabilitate mai redusă decât o sesiune de desktop sau web. Operațiunile declarate ca exclusiv pentru clientul complet sunt refuzate pentru un telefon înainte ca handlerul să ruleze, indiferent cât de privilegiat este utilizatorul din spate: emiterea, listarea, redenumirea și revocarea asocierilor de dispozitive; citirea și setarea conectivității prin tunel; backupul serverului și exportul/importul spațiului de lucru; detectarea și terminarea proceselor; probele de adaptoare; setările de server; administrarea SSO; controlul flotei; și preluarea sau predarea unui agent aflat în rulare.

3. O listă de permitere cu refuz implicit pentru instrumente

Secțiune intitulată „3. O listă de permitere cu refuz implicit pentru instrumente”

Pentru suprafața de instrumente MCP în special (tools/call), o listă de permitere cu refuz implicit guvernează ce instrumente poate invoca telefonul. Orice nu este în listă este respins înainte de a rula. Lista este dominată de operațiuni de citire și observare, plus o mână de scrieri doar locale — un mesaj, o actualizare de tichet, un marcaj pe un articol — care nu cheltuie buget LLM, nu pornesc niciun proces și nu ating niciun sistem extern.

Refuzate, de exemplu: consultarea unui agent, pornirea unei revizuiri IA, terminarea unui agent, publicarea unei revizuiri pe GitHub, angajarea sau concedierea agenților, crearea unui spațiu de lucru.

Serverul nu păstrează niciun “spațiu de lucru curent”. Este fără stare prin proiectare: fiecare apel delimitat de spațiul de lucru trebuie să numească workspace_id-ul țintă în argumentele sale, iar dispatcherul refuză apelul de la bun început atunci când acesta lipsește sau numește un spațiu de lucru pe care serverul nu îl are înregistrat — înainte ca ceva să deschidă o bază de date. Un telefon nu poate, prin urmare, nici să moștenească, nici să alunece în domeniul altui client, iar numirea unui spațiu de lucru străin nu ajută nici ea, pentru că verificarea apartenenței de la poarta 1 se aplică în continuare. Aceasta este aceeași invariantă de izolare a spațiilor de lucru pe care o impune restul produsului.

Fiecare cadru dintre telefon și server este sigilat cu cheia de asociere; tokenul de admitere doar aduce un client în cameră, nu decriptează nimic. Brokerul retransmite text cifrat și nu vede niciodată cheia. Un dispozitiv revocat își găsește credențialul deja dispărut, așa că eșuează închis la reconectare.

Un credențial emis din aplicație este limitat la 30 de zile; după aceea, poarta de conectare îl respinge și telefonul trebuie să se asocieze din nou. Revocarea este în timp real: serverul supraveghează tabelul de dispozitive și închide sesiunile deschise ale unui dispozitiv revocat în câteva secunde, în loc să aștepte următoarea lui conectare.

Un limitator cu fereastră glisantă plafonează traficul de instrumente remote la 120 de apeluri pe minut, cu un subplafon mai strict de 30 pe minut pentru verbele care modifică date. Bugetul aparține principalului, nu sesiunii: trei dintre dispozitivele tale trag dintr-o singură alocație, așa că un client deturnat nu poate cumpăra spațiu suplimentar deschizând mai multe sesiuni, iar un membru gălăgios nu îi poate înfometa pe ceilalți.

Brokerul de releu este deliberat simplu: găzduiește camere, retransmite cadre sigilate și nu deține conturi, date ale aplicației sau chei. Camerele sunt cu acces pe bază de invitație și efemere. Datele aplicației, audio-ul, transcrierea, sursa și credențialele rămân toate pe server.

Odată asociat, telefonul primește actualizări în timp real sub formă de cadre de notificare — mesaje noi de la agenți, tichete atribuite ție, schimbări de stare — în oglindă cu notificările desktopului. Serverul difuzează acele cadre către fiecare sesiune conectată, iar filtrul de spațiu de lucru este aplicat pe partea de client, așa că ceea ce vezi este delimitat la spațiul de lucru la care te uiți.

Suprafață Ce arată
Setări → Tu → Dispozitivele tale (/workspaces/:workspaceId/settings/you/devices) Clienți asociați cu stare în timp real, plus Asociază un client nou (browser web, aplicație de desktop sau telefon) și revocare

Același panou emite asocieri și pentru un al doilea browser sau o a doua aplicație de desktop, nu doar pentru telefoane — fluxul este identic, doar linkul profund diferă.