personal-server-kit 0.2.0

Your own 24x7 server for AI work, set up with one command. Seu próprio servidor 24x7 para trabalhar com IA, montado com um comando.

Your AI sessions keep running when the laptop closes, on a machine you own, with backups, alerts on your phone and a place for your second brain.

Suas sessões de IA continuam rodando quando o notebook fecha, numa máquina sua, com backup, avisos no celular e um lugar para o seu second brain.

curl -fsSL https://raw.githubusercontent.com/ogabrielalonso/personal-server-kit/main/install.sh | bash
Personal Server Kit 0.2.0
  1. NetworkRedeprivate, Tailscaleprivada, Tailscale
  2. AlertsAvisostest confirmedteste confirmado
  3. BackupBackuprestore comparedrestauração comparada
  4. LockdownBloqueiokept by your laptopmantido pelo notebook
  5. Brain slotSlot do brainits own memorymemória própria
  6. Reboot proofProva de rebootresult on your phoneresultado no celular
myserver 15 of 15 checks passed. The installation is complete.15 de 15 verificações passaram. A instalação está completa.
Each lamp is a promise the installer checks. It turns green only when its proof passes. Press Reboot to watch the final proof. Example server and count. Cada lâmpada é uma promessa que o instalador confere. Ela só fica verde quando a prova passa. Aperte Reboot para ver a prova final. Servidor e contagem de exemplo.

What the installer printsO que o instalador mostra

One question at a time, then each step checks, acts and proves. If a step fails, you get one sentence, a next action and a diagnostic file; running it again resumes where it stopped.Uma pergunta por vez, e cada passo confere, age e prova. Se um passo falhar, você recebe uma frase, a próxima ação e um arquivo de diagnóstico; rodar de novo continua de onde parou.

owner@server: ~ installer, first runinstalador, primeira execução
$ curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash

Language / Idioma
  [1] English  (default)
  [2] Português
Choose 1-2 (Enter for default): (Enter)

personal-server-kit 0.2.0
-------------------------

What is this computer?
  [1] My always-on server (this Linux machine)  (default)
  [2] My computer: connect it to a server I already set up
Choose 1-2 (Enter for default): 1
      ...
[1/20] Your user account
  ok  already in place
      ...
[12/20] Private network (Tailscale)
  ok  done
      ...
[15/20] Encrypted backup
      Running the first backup and a restore test...
  ok  Backup works: 12 files restored and compared.
      ...
[17/20] Connect your laptop
  +----------------------------------------------------------------+
  | Now connect your laptop to this server.                        |
  |                                                                |
  | On your laptop, open a terminal and run:                       |
  |   curl -fsSL .../install.sh | bash                             |
  | Choose 'connect it to a server' and enter:                     |
  |                                                                |
  |   Server address:  100.64.0.7                                  |
  |   Pairing code:    K7QX-M4RW                                   |
  |                                                                |
  | The laptop needs Tailscale too, signed in to the same account. |
  +----------------------------------------------------------------+
      Waiting for the laptop (15 min left)..._
$ curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash

Language / Idioma
  [1] English  (default)
  [2] Português
Choose 1-2 (Enter for default): 2

personal-server-kit 0.2.0
-------------------------

O que é este computador?
  [1] Meu servidor sempre ligado (esta máquina Linux)  (padrão)
  [2] Meu computador: conectar a um servidor que já configurei
Escolha 1-2 (Enter para o padrão): 1
      ...
[1/20] Sua conta de usuário
  ok  já estava pronto
      ...
[12/20] Rede privada (Tailscale)
  ok  feito
      ...
[15/20] Backup criptografado
      Rodando o primeiro backup e um teste de restauração...
  ok  O backup funciona: 12 arquivos restaurados e comparados.
      ...
[17/20] Conectar seu laptop
  +-------------------------------------------------------+
  | Agora conecte seu laptop a este servidor.             |
  |                                                       |
  | No laptop, abra um terminal e rode:                   |
  |   curl -fsSL .../install.sh | bash                    |
  | Escolha 'conectar a um servidor' e informe:           |
  |                                                       |
  |   Endereço do servidor:  100.64.0.7                   |
  |   Código de pareamento:  K7QX-M4RW                    |
  |                                                       |
  | O laptop também precisa do Tailscale, na mesma conta. |
  +-------------------------------------------------------+
      Aguardando o laptop (faltam 15 min)..._
Real installer text, shortened where you see "...". Address and code are examples. The first question is always the language; English is the default. Texto real do instalador, encurtado onde aparece "...". Endereço e código são exemplos. A primeira pergunta é sempre o idioma; inglês é o padrão.

In one minuteEm 1 minuto

For anyone who has never set up a server. No jargon in this part; every technical detail is further down the page, for whoever wants it.

Para quem nunca montou um servidor. Esta parte não tem termo técnico; os detalhes ficam mais abaixo na página, para quem quiser.

What it isO que é

An installer that turns an always-on Linux computer into your own server for AI work. It applies and checks the dozens of settings a system administrator would otherwise make by hand, so you do not need to be one.

Um instalador que transforma um computador Linux sempre ligado no seu servidor pessoal para trabalhar com IA. Ele aplica e confere as dezenas de ajustes que um administrador de sistemas faria à mão, então você não precisa ser um.

Who it is forPara quem é

People who work with AI assistants that act directly on files, such as Claude Code or Codex, and want them running somewhere that stays on when the laptop closes. If you only use AI in the browser, you do not need this yet.

Quem trabalha com assistentes de IA que mexem direto nos arquivos, como Claude Code ou Codex, e quer que eles rodem num lugar que continua ligado quando o notebook fecha. Se você só usa IA pelo navegador, ainda não precisa disto.

What you getO que você ganha

A server closed to the internet and open only to your own devices, an encrypted backup that is tested every week, alerts on your phone only when something needs you, and a machine that comes back by itself after a restart.

Um servidor fechado para a internet e aberto só para os seus aparelhos, um backup criptografado testado toda semana, avisos no celular só quando algo precisa de você e uma máquina que volta sozinha depois de reiniciar.

Your server in one picture: open to your laptop over the private network, alerts to your phone, closed to the internet Internet scans and attacksvarreduras e ataques Your phoneSeu celular Telegram or ntfyTelegram ou ntfy Your laptopSeu notebook macOS or LinuxmacOS ou Linux Your serverSeu servidor Ubuntu 24.04 · always onUbuntu 24.04 · sempre ligado second brain slotlugar do second brain its own memorymemória própria encrypted backupbackup criptografado tested every weektestado toda semana firewall open to your devices onlyaberto só aos seus aparelhos health checksaúde conferida every 5 minutesa cada 5 minutos blockedbloqueada alertsavisos Tailscale
Your server in one picture: open to your laptop over the private network, alerts to your phone, closed to the internet Internet Your phoneSeu celular Your laptopSeu notebook Your serverSeu servidor Ubuntu 24.04 · always onUbuntu 24.04 · sempre ligado second brain slotlugar do second brain its own memorymemória própria encrypted backupbackup criptografado tested every weektestado toda semana firewall open to your devices onlyaberto só aos seus aparelhos health checksaúde conferida every 5 minutesa cada 5 minutos blockedbloqueada alertsavisos Tailscale
Closed to the internet, open to your own devices, and it tells your phone when something needs you.
Fechado para a internet, aberto para os seus aparelhos, e avisa o seu celular quando algo precisa de você.

What you need

O que você precisa

four things, all on hand before you startquatro coisas, todas à mão antes de começar
  • A computer that stays onUm computador que fica ligadoA rented cloud server (a VPS) or an old PC. At least 4 GB of memory and 10 GB free.Um servidor alugado na nuvem (um VPS) ou um PC antigo. No mínimo 4 GB de memória e 10 GB livres.
    Ubuntu 24.04
  • A Tailscale accountUma conta no TailscaleThe private network that links your devices to the server without opening it to the internet.A rede privada que liga os seus aparelhos ao servidor, sem abri-lo para a internet.
    free personal planplano pessoal gratuito
  • Your phoneO seu celularTo receive alerts when something needs you, plus one summary a day.Para receber os avisos quando algo precisa de você, e um resumo por dia.
    Telegramntfy
  • A place for the backupUm lugar para o backupTo keep the backup copies away from the server, locked with a password only you have.Para guardar as cópias de segurança fora do servidor, trancadas com uma senha que só você tem.
    S3 or another PCS3 ou outro PC seu

An unfamiliar word? The glossary near the end explains each one in plain words.

Alguma palavra estranha? O glossário perto do fim explica cada uma em palavras simples.

What you actually doO que você faz, na prática

Five steps, from an empty machine to a server that looks after itself. The installer does everything else; on a test machine the whole install took under 10 minutes, not counting creating the accounts.

Cinco passos, de uma máquina vazia a um servidor que se cuida sozinho. O resto é com o instalador; numa máquina de teste, a instalação inteira levou menos de 10 minutos, sem contar a criação das contas.

  1. 1

    Pick the machine

    Escolha a máquina

    Rent a small cloud server (a VPS) or use an old PC with Ubuntu 24.04. It is the one that stays on.

    Alugue um servidor pequeno na nuvem (um VPS) ou use um PC antigo com Ubuntu 24.04. É ele que vai ficar ligado.

    VPSold PCPC antigoUbuntu 24.04
  2. 2

    Paste one command

    Cole um comando

    Open the machine's terminal: on a rented server, through the provider's web console or the login it gives you; on a PC, through its Terminal app. Paste the line at the top of this page; the first question is the language.

    Abra o terminal da máquina: num servidor alugado, pelo console no site do provedor ou pelo acesso que ele te passa; num PC, pelo app Terminal. Cole a linha do topo desta página; a primeira pergunta é o idioma.

    $ curl -fsSL …/install.sh | bash
  3. 3

    Answer a few questions

    Responda poucas perguntas

    Server name, time zone, where alerts go and where the backup lives. Nothing changes until it has checked the machine and shown you a summary.

    Nome do servidor, fuso horário, para onde vão os avisos e onde fica o backup. Nada muda antes de ele conferir a máquina e mostrar um resumo.

    languageidiomanamenometime zonefusoalertsavisosbackup
  4. 4

    Connect your laptop

    Conecte seu notebook

    The server shows its address on your private network and an 8 character code. On the laptop you run the same command (the installer also sets up laptops), choose to connect to a server and type both.

    O servidor mostra o endereço dele na sua rede privada e um código de 8 caracteres. No notebook, você roda o mesmo comando (o instalador também prepara notebooks), escolhe conectar a um servidor e digita os dois.

    K7QX-M4RW
  5. 5

    Done

    Pronto

    The server closes itself to the internet, restarts to prove everything comes back, and sends the result to your phone.

    O servidor se fecha para a internet, reinicia para provar que tudo volta e manda o resultado para o seu celular.

    myserver: back online after the rebootmyserver: de volta depois do reboot15 of 15 checks passed. The installation is complete.15 de 15 verificações passaram. A instalação está completa.

If a step fails, the installer stops, says in one sentence what happened and what to do, and picks up where it stopped when you run it again. If you change your mind, one command undoes what the kit installed and keeps your data.

That is enough to decide. The sections below explain each part in more depth: why each rule exists, how the install works, the security and the proof.

Se um passo falhar, o instalador para, diz em uma frase o que aconteceu e o que fazer, e continua de onde parou quando você rodar de novo. E se mudar de ideia, um comando desfaz o que o kit instalou e mantém os seus dados.

Isso é o essencial para decidir. As seções abaixo explicam cada parte com mais detalhe: por que cada regra existe, como a instalação funciona, a segurança e as provas.

in the code:no código: docs/STRUCTURE.md · docs/HOST-BRAIN-CONTRACT.md

Every setting answers a failure that is common on always-on serversCada configuração responde a uma falha comum em servidores sempre ligados

A server that stays on day and night tends to break for the same few reasons: the disk fills up, memory runs out, remote access does not come back after a restart, and alerts turn into noise nobody reads. The kit ships a ready rule for each one. On the right, the first sentence says what you get; the rest is the technical detail.

Um servidor que fica ligado dia e noite costuma quebrar sempre pelos mesmos motivos: o disco enche, a memória acaba, o acesso não volta depois de reiniciar, e os avisos viram barulho que ninguém lê. O kit traz uma regra pronta para cada um. À direita, a primeira frase diz o que você ganha; o resto é o detalhe técnico.

What goes wrong, and what the kit does

O que costuma dar errado, e o que o kit faz

one rule per common failureuma regra para cada falha comum
Common failureFalha comumIn the kitNo kit
SSH

After a restart, remote access sometimes never comes back, for example when a second access service starts before the network is ready.

Depois de reiniciar, o acesso remoto às vezes não volta, por exemplo quando um segundo serviço de acesso sobe antes de a rede estar pronta.

ruleregra

Remote access always comes back after a restart.

O acesso remoto sempre volta depois de reiniciar.

One standard sshd, filtered by the firewall instead of bound to the tailnet; /run/sshd created at every boot; the install ends with a real reboot.

Um único sshd padrão, filtrado pelo firewall em vez de preso ao IP da tailnet; /run/sshd criado a cada boot; a instalação termina com um reboot de verdade.

lockdown.py · prove.py
sessionssessões

A device that silently stops sending its sessions can go unnoticed for days.

Um dispositivo que para de enviar suas sessões em silêncio pode passar dias sem ninguém perceber.

ruleregra

You find out when a device stops sending.

Você fica sabendo quando um aparelho para de enviar.

Every device leaves a delivery receipt; three silent days show up in the daily summary.

Cada dispositivo deixa um recibo de entrega; três dias de silêncio aparecem no resumo diário.

bridge.py · checks.py
diskdisco

Forgotten temporary files and AI assistants' histories, which only grow, fill the main disk.

Arquivos temporários esquecidos e históricos dos assistentes de IA, que só crescem, enchem o disco principal.

ruleregra

The disk does not fill up with leftovers.

O disco não enche com sobras.

/tmp cleaned after 10 days, orphan browsers and dev servers reaped, agent histories reported daily and never deleted.

/tmp limpo após 10 dias, navegadores e dev servers órfãos encerrados, históricos de agentes reportados todo dia e nunca apagados.

tmpfiles · runtime/reaper.py
memorymemória

Memory limits set one by one can add up to more than the machine has, leaving nothing to protect the system.

Limites de memória definidos um a um podem somar mais do que a máquina tem, sem sobrar nada para proteger o sistema.

ruleregra

Memory is never promised beyond what the machine has.

A memória nunca é prometida além do que a máquina tem.

Limits computed from the machine's RAM; their sum always stays below it, with a margin for the kernel.

Limites calculados a partir da RAM da máquina; a soma sempre fica abaixo dela, com margem para o kernel.

budget.py
alertsalertas

An alert that fires on every check repeats all day while disk usage hovers near the threshold.

Um alerta que dispara a cada verificação se repete o dia todo enquanto o uso do disco oscila perto do limite.

ruleregra

Few alerts, and only the ones that matter.

Poucos avisos, e só os que importam.

One stable key per problem, a margin to clear it, one message when it starts, changes or clears, a reminder once a day.

Uma chave estável por problema, margem para sair do alerta, uma mensagem quando começa, muda ou termina, e um lembrete por dia.

alerts.py · notify.py
backup

Backups sent to a laptop fail whenever the laptop is asleep.

Backups enviados para um laptop falham sempre que ele está dormindo.

ruleregra

The backup never depends on a laptop being on, and it is tested.

O backup nunca depende de um notebook ligado, e é testado.

No default destination depends on a laptop; an evening retry; a weekly restore test compared by hash.

Nenhum destino padrão depende de laptop; nova tentativa à noite; teste de restauração semanal comparado por hash.

setup_backup.py · runtime/backup.py
ownershipposse

When two tools manage the same services, each one undoes the other's changes.

Quando duas ferramentas gerenciam os mesmos serviços, uma desfaz as mudanças da outra.

ruleregra

Only one tool manages the server's services.

Só uma ferramenta cuida dos serviços do servidor.

The host installs every unit. The brain only declares what it needs, in a manifest.

O host instala todas as units. O brain só declara o que precisa, num manifesto.

manifest.py · brainslot.py
in the code:no código: pskit/install.py · pskit/linux · pskit/device

One installer, three rolesUm instalador, três papéis

The second question the installer asks is what this computer is. Each answer runs a different scenario. The server runs Linux on any machine the owner already has; the laptop can be a Mac or a Linux machine.

A segunda pergunta do instalador é o que este computador é. Cada resposta roda um cenário diferente. O servidor roda Linux em qualquer máquina que o dono já tenha; o laptop pode ser um Mac ou uma máquina Linux.

Linux server

Servidor Linux

A rented VPS or an old PC with Ubuntu 24.04. The reference scenario.

Um VPS alugado ou um PC antigo com Ubuntu 24.04. O cenário de referência.

  • 22 steps, each one checked22 passos, cada um conferido
  • memory limits the machine enforceslimites de memória que a própria máquina garante
  • ends with a real reboottermina com um reboot de verdade
complete · tested end to endcompleto · testado ponta a ponta

Laptop

Laptop

Connects the owner's laptop to a server with a pairing code shown on the server's screen.

Conecta o laptop do dono a um servidor com um código de pareamento que aparece na tela do servidor.

  • three keys, each good for one job onlytrês chaves, cada uma só para uma tarefa
  • a link to the second brain that reconnects by itselfuma ligação com o second brain que se refaz sozinha
  • session delivery every 15 minutesentrega de sessões a cada 15 minutos
tested on Linux onlytestado só em Linux

Local only

Só local

No server at all. The installer says so plainly and hands off to the brain kit on the laptop.

Nenhum servidor. O instalador diz isso com clareza e passa a vez para o kit do brain no laptop.

  • nothing to install on a servernada para instalar num servidor
  • second brain jobs run only while the laptop is awakeas tarefas do second brain só rodam com o notebook acordado
  • add a server later by running the installer on itdá para adicionar um servidor depois, rodando o instalador nele
hand-off · no serverrepasse · sem servidor
in the code:no código: pskit/ · docs/STRUCTURE.md

The whole picture on one pageO quadro completo numa página

Think of the server as a house with a single door that opens only for your own devices: the laptop and the server talk over a private network, and nothing on the server is exposed to the internet. The kit looks after the house (access, memory, alerts, backup); the second brain lives in a room the kit prepares for it, with written rules about what each side may do.

Pense no servidor como uma casa com uma única porta, que só abre para os seus aparelhos: o notebook e o servidor conversam por uma rede privada, e nada no servidor fica exposto à internet. O kit cuida da casa (acesso, memória, avisos, backup); o second brain mora num quarto que o kit prepara para ele, com regras escritas sobre o que cada lado pode fazer.

Architecture: laptop, private network, server with host layer and brain slot Owner's laptopLaptop do dono macOS or LinuxmacOS ou Linux Your terminalSeu terminal ssh <server>: owner shellssh <servidor>: shell do dono Session pushEnvio de sessões Claude · Codex · Grok, 15 min Brain tunnelTúnel do brain 127.0.0.1:8799 to the server127.0.0.1:8799 até o servidor Pinned host keysChaves do host fixadas known_hosts per serverknown_hosts por servidor Public internetInternet pública scans, password guessingvarreduras, chute de senha refused by the firewallrecusada pelo firewall Private networkRede privada Tailscale · WireGuard owner: full shelldono: shell completo bridge: receiver onlyponte: só o receptor tunnel: port 8799 onlytúnel: só a porta 8799 pairing: port 47800pareamento: porta 47800 8-char code · 15 mincódigo de 8 · 15 min Your serverSeu servidor Ubuntu 24.04 · a VPS or an old PC · always onUbuntu 24.04 · VPS ou PC antigo · sempre ligado Front doorEntrada sshd keys onlysó chave ufw tailnet onlysó tailnet no root loginsem login root owner onlysó o dono UDP 41641 onlysó UDP 41641 HOST LAYER · THIS REPOSITORYCAMADA HOST · ESTE REPOSITÓRIO Memory limitsLimites de memória brain · sessions · CIbrain · sessões · CI AlertsAlertas spool, root, your phonespool, root, seu celular Backup restic · weekly restorerestic · restore semanal Session receiverReceptor de sessões bridge-receive Health + summarySaúde + resumo every 5 min · 19:00a cada 5 min · 19:00 GuardsGuardas orphans · pressureórfãos · pressão installs every unitinstala todas as units contract: host.json + manifest.jsoncontrato: host.json + manifest.json BRAIN SLOT · SEPARATE PROJECTLUGAR DO BRAIN · PROJETO SEPARADO Home + inbox /srv/<name>/brain/srv/<nome>/brain inbox/sessions/ user pskit-brainusuário pskit-brain Brain servicesServiços do brain from manifest.jsondo manifest.json units made by the hostunits criadas pelo host pskit-brain.slice Query portPorta de consulta 127.0.0.1:8799 loopback onlysó loopback health every 5 minsaúde a cada 5 min sessionssessões Your phoneSeu celular Telegram or ntfyTelegram ou ntfy Backup storageDestino do backup S3 or another machineS3 ou outra máquina Outside watcherVigia externo dead-man heartbeatheartbeat dead-man outgoing connections onlysó conexões de saída
Architecture: laptop, private network, server with host layer and brain slot Owner's laptopLaptop do dono macOS or LinuxmacOS ou Linux Your terminalSeu terminal ssh <server>: owner shellssh <servidor>: shell do dono Session pushEnvio de sessões Claude · Codex · Grok, 15 min Brain tunnelTúnel do brain 127.0.0.1:8799 to the server127.0.0.1:8799 até o servidor Pinned host keysChaves do host fixadas known_hosts per serverknown_hosts por servidor Private networkRede privada Tailscale · WireGuard owner: full shelldono: shell completo bridge: receiver onlyponte: só o receptor tunnel: port 8799 onlytúnel: só a porta 8799 pairing: port 47800pareamento: porta 47800 8-char code · 15 mincódigo de 8 · 15 min Public internetInternet pública scans, password guessingvarreduras, chute de senha Your serverSeu servidor Ubuntu 24.04 · always onUbuntu 24.04 · sempre ligado a VPS or an old PCVPS ou PC antigo Front doorEntrada sshd keys onlysó chave no root loginsem login root owner onlysó o dono ufw tailnet onlysó tailnet UDP 41641 onlysó UDP 41641 HOST LAYER · THIS REPOSITORYCAMADA HOST · ESTE REPOSITÓRIO installs every unitinstala todas as units Memory limitsLimites de memória brain · sessions · CIbrain · sessões · CI AlertsAlertas spool, root, your phonespool, root, seu celular Backup restic · weekly restorerestic · restore semanal Session receiverReceptor de sessões bridge-receive Health + summarySaúde + resumo every 5 min · 19:00a cada 5 min · 19:00 GuardsGuardas orphans · pressureórfãos · pressão contract: host.json + manifest.jsoncontrato: host.json + manifest.json BRAIN SLOT · SEPARATE PROJECTLUGAR DO BRAIN · PROJETO SEPARADO Home + inbox /srv/<name>/brain/srv/<nome>/brain inbox/sessions/ user pskit-brainusuário pskit-brain Brain servicesServiços do brain from manifest.jsondo manifest.json units made by the hostunits criadas pelo host pskit-brain.slice Query portPorta de consulta 127.0.0.1:8799 loopback onlysó loopback health every 5 minsaúde a cada 5 min refused by the firewallrecusada pelo firewall outgoing connections onlysó conexões de saída Your phoneSeu celular Telegram or ntfyTelegram ou ntfy Backup storageDestino do backup S3 or another machineS3 ou outra máquina Outside watcherVigia externo dead-man heartbeatheartbeat dead-man
owner key: full access (shell)chave do dono: acesso completo (shell) bridge key: can only deliver sessionschave da ponte: só entrega sessões tunnel key: can only reach port 8799chave do túnel: só alcança a porta 8799
host layer (this repository)camada host (este repositório) brain slot (separate project)lugar do brain (projeto separado)
in the code:no código: pskit/install.py · pskit/steps.py · pskit/state.py · docs/INSTALLER.md

An installer that proves every stepUm instalador que comprova cada passo

It was written for people who are not system administrators. The questions are plain; when something blocks, you get one sentence and the next thing to do; and a machine is never left half configured. Nothing changes until the pre-check passes.

Foi escrito para quem não é administrador de sistemas. As perguntas são simples; quando algo bloqueia, você recebe uma frase e a próxima ação; e nenhuma máquina fica configurada pela metade. Nada muda antes da pré-checagem passar.

What it asks, in order

O que ele pergunta, em ordem

later steps ask only what they needos passos seguintes só perguntam o que precisam
  1. 1LanguageIdioma
  2. 2What is this computer?O que é este computador?
  3. 3Server nameNome do servidor
  4. 4Owner accountConta do dono
  5. 5Time zoneFuso horário
  6. 6Optional modulesMódulos opcionais
  7. 7Pre-check and summary, then continue?Pré-checagem e resumo, e continuar?

Every step, the same loop

Todo passo, o mesmo ciclo

check already right?já está certo? apply change + ledgermuda + registra verify prove the resultcomprova o resultado nonão skip already in placejá estava pronto yessim donefeito journal: donejournal: feito passespassa stoppara 1 sentence + diag file1 frase + diagnóstico failsfalha next steppróximo passo run again: it resumes hererode de novo: retoma daqui
check already right?já está certo? apply change + ledgermuda + registra verify prove the resultcomprova o resultado nonão skip already in placejá estava pronto yessim donefeito journal: donejournal: feito stoppara 1 sentence + diag file1 frase + diagnóstico failsfalha run again: it resumes hererode de novo: retoma daqui next steppróximo passo
  • Resumable

    Retomável

    Run it again and it continues where it stopped. Finished steps are re-checked against the real machine, never blindly re-applied.

    Rode de novo e ele continua de onde parou. Passos concluídos são reconferidos na máquina real, nunca reaplicados às cegas.

  • Reversible

    Reversível

    Every change is written down in a log (the ledger). pskit uninstall undoes it and keeps your data; files you edited afterwards are left alone.

    Toda mudança fica anotada num registro (o ledger). pskit uninstall desfaz tudo e mantém seus dados; arquivos que você editou depois ficam como estão.

  • The only risky step protects itself

    O único passo arriscado se protege

    Closing public access is armed with a 10-minute automatic undo that also survives a reboot.

    Fechar o acesso público é armado com um desfazer automático de 10 minutos que sobrevive até a um reboot.

  • A diagnostic file, safe to send

    Um arquivo de diagnóstico seguro para enviar

    When a step fails you get its path. Tokens, keys, passwords, ping URLs and public addresses are redacted.

    Quando um passo falha, você recebe o caminho dele. Tokens, chaves, senhas, URLs de ping e endereços públicos saem apagados.

  • Unattended when you need it

    Sem interação quando precisar

    Every question has a key in an answers file. Secrets never go there; they come from environment variables.

    Toda pergunta tem uma chave num arquivo de respostas. Segredos nunca vão nele; vêm de variáveis de ambiente.

The 22 steps on a Linux server

Os 22 passos num servidor Linux

select a step · dashed = optional module · copper number = the risky oneselecione um passo · tracejado = módulo opcional · número cobre = o arriscado
FoundationBasesteps 1 to 11passos 1 a 11
Reach and safetyAlcance e segurançasteps 12 to 15passos 12 a 15
ServicesServiçossteps 16 to 18passos 16 a 18
Your laptopSeu laptopsteps 19 to 20passos 19 a 20
Brain and proofBrain e provasteps 21 to 22passos 21 a 22
01step 1 of 22 · Foundationpasso 1 de 22 · Base

Your user accountSua conta de usuário

What it does
O que faz
Creates the owner if missing (only when the installer runs as root) and sets the sudo password.Cria o dono se ele não existir (só quando o instalador roda como root) e define a senha do sudo.
How it is verified
Como é verificado
The account exists.A conta existe.
Code
Código
pskit/linux/steps_base.py · OwnerAccount
in the code:no código: pskit/lockdown.py · pskit/server/pairing.py · pskit/server/keys.py · docs/SECURITY.md

Closing the door without locking yourself outFechar a porta sem se trancar do lado de fora

Closing the server to the internet is the only step that could lock you out, so it is never done blindly. The kit saves how things were, arms an automatic undo of 10 minutes, closes the door and waits for your laptop to prove it can still get in. If it cannot, everything goes back on its own.

Fechar o servidor para a internet é o único passo que poderia deixar você do lado de fora, então ele nunca é feito às cegas. O kit guarda como estava, arma um desfazer automático de 10 minutos, fecha a porta e espera o seu notebook provar que ainda consegue entrar. Se não conseguir, tudo volta sozinho.

ON THE SERVERNO SERVIDOR 1 Snapshot sshd + ufw as they arecomo estão 2 Arm the undoArmar o desfazer 10 min timertimer de 10 min also on boottambém no boot 3 ApplyAplicar keys onlysó chave tailnet onlysó tailnet 4 ReadyPronto confirm allowedpode confirmar from now ona partir daqui A failure while applying restores the snapshot at once.Uma falha durante a aplicação restaura o snapshot na hora. Confirmation is refused until the changes are in place.A confirmação é recusada até as mudanças estarem aplicadas. Only tailnet addresses count: 100.64.0.0/10, fd7a:115c:a1e0::/48.Só endereços da tailnet contam: 100.64.0.0/10, fd7a:115c:a1e0::/48. Existing firewall rules are shown; you choose to keep them or not.As regras de firewall existentes aparecem; você escolhe se mantém. 0 2 4 6 8 10 min undo timer runningtimer do desfazer correndo ON THE LAPTOPNO LAPTOP The laptop confirmsO laptop confirma ssh <server> pskit confirm-lockdown --wait 300ssh <servidor> pskit confirm-lockdown --wait 300 at the end of pairing, by itselfno fim do pareamento, sozinho KeptMantido timer disarmedtimer desarmado access closedacesso fechado No confirmation in 10 minutesSem confirmação em 10 minutos snapshot restored + alert 'access restored'snapshot restaurado + alerta 'acesso restaurado'
ON THE SERVERNO SERVIDOR 1 Snapshot sshd + ufw · as they aresshd + ufw · como estão 2 Arm the undoArmar o desfazer 10 min timer · also on boottimer de 10 min · também no boot 3 ApplyAplicar keys only · tailnet onlysó chave · só tailnet 4 ReadyPronto confirm allowed · from now onpode confirmar · a partir daqui 0 2 4 6 8 10 min undo timer runningtimer do desfazer correndo ON THE LAPTOPNO LAPTOP The laptop confirmsO laptop confirma ssh <server> pskit confirm-lockdownssh <servidor> pskit confirm-lockdown --wait 300 at the end of pairing, by itselfno fim do pareamento, sozinho KeptMantido timer disarmed · access closedtimer desarmado · acesso fechado No confirmation in 10 minutesSem confirmação em 10 minutos snapshot restored + alertsnapshot restaurado + alerta 'access restored''acesso restaurado' A failure while applying restores theUma falha durante a aplicação restaura o snapshot at once.snapshot na hora. Confirmation is refused until theA confirmação é recusada até as changes are in place.mudanças estarem aplicadas. Only tailnet addresses count:Só endereços da tailnet contam: 100.64.0.0/10, fd7a:115c:a1e0::/48. Existing firewall rules are shown; youAs regras de firewall existentes aparecem; choose to keep them or not.você escolhe se mantém.

Pairing, and the three keys it creates

O pareamento e as três chaves que ele cria

no confusing first-connection warning to misreadsem aquele alerta de primeira conexão que ninguém entende
The server showsO servidor mostra
K7QX-M4RW

Example code. Its alphabet leaves out the characters people confuse:

Código de exemplo. O alfabeto deixa de fora os caracteres que as pessoas confundem:

0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

~40 bits8 characters from 31 symbols8 caracteres de 31 símbolos
15 minone device per pairing sessionum dispositivo por sessão
5wrong codes end the sessioncódigos errados encerram a sessão
47800pairing port, open on the private network onlyporta do pareamento, aberta só na rede privada
pinnedfixadasthe laptop saves the server's identity, so an impostor is refusedo notebook guarda a identidade do servidor, então um impostor é recusado
16 MiBfirst session push, right after pairingprimeiro envio de sessões, logo após o pareamento

Technical detail, found while testing: restrict alone does not stop a key from running commands, and adding port-forwarding also re-enables remote listens. Hence command= and permitlisten, both proven on a real sshd. A lost laptop is revoked with sudo pskit forget-device <name>: all three keys at once.

Detalhe técnico, descoberto nos testes: restrict sozinho não impede uma chave de rodar comandos, e adicionar port-forwarding reabilita escutas remotas. Por isso o command= e o permitlisten, os dois comprovados num sshd real. Um laptop perdido é revogado com sudo pskit forget-device <nome>: as três chaves de uma vez.

Owner keyChave do dono

your shellseu shell
canpode

log in as the owner and use sudo with your password

entrar como o dono e usar sudo com a sua senha

for everyonepara todos

passwords off for SSH, root login off, only the owner allowed

senha desligada no SSH, login root desligado, só o dono permitido

Tunnel keyChave do túnel

brain port onlysó a porta do brain
restrict,port-forwarding,permitopen="127.0.0.1:8799",permitlisten="127.0.0.1:1",command="/usr/bin/false"
canpode

carry the laptop's 127.0.0.1:8799 to the brain's port

levar o 127.0.0.1:8799 do laptop até a porta do brain

cannotnão pode

run commands, reach other ports, or open a way back into the server

rodar comandos, alcançar outras portas ou abrir um caminho de volta para dentro do servidor

Bridge keyChave da ponte

sessions onlysó sessões
restrict,command="/usr/local/bin/pskit bridge-receive --device <name>"
canpode

deliver session files into its own device folder

entregar arquivos de sessão na pasta do próprio dispositivo

cannotnão pode

open a shell, forward ports, or write anywhere else

abrir um shell, encaminhar portas ou escrever em outro lugar

What it protects against, and what it does not

Contra o que protege, e contra o que não protege

Internet scans, password guessing

Varreduras e chute de senha

Nothing listens publicly; keys only, owner only.

Nada escuta em público; só chave, só o dono.

A stolen laptop key

Uma chave de laptop roubada

Two of the three keys cannot open a shell; one command revokes all.

Duas das três chaves não abrem shell; um comando revoga todas.

An impostor server

Um servidor impostor

Host keys pinned at pairing, strict checking on.

Chaves do host fixadas no pareamento, checagem estrita ligada.

The brain wandering off

O brain saindo do lugar

Own user; read-only system and no homes; writes only to its home, the spool and the lock.

Usuário próprio; sistema somente leitura e sem acesso às homes; escreve só na sua casa, no spool e na trava.

Channel tokens leaking

Vazamento de tokens do canal

Only root delivers alerts; the token lives in a root-only folder.

Só o root entrega alertas; o token fica numa pasta só do root.

A hostile session upload

Um envio de sessões malicioso

Known agent trees only; no .., no symlinks; headers validated; atomic writes.

Só as árvores conhecidas dos agentes; sem .., sem symlinks; cabeçalhos validados; escrita atômica.

Tampered downloads

Downloads adulterados

Tailscale from its signed repository; restic checked against its SHA-256.

Tailscale do repositório assinado; restic conferido pelo SHA-256.

Secrets in support requests

Segredos em pedidos de ajuda

The diagnostic file lists secret files, never their content.

O diagnóstico lista os arquivos secretos, nunca o conteúdo.

Not covered

Não coberto

A compromised Tailscale account (use 2FA), a compromised owner account, the VPS provider's access to the live disk, and Tailscale key expiry if left on.

Uma conta Tailscale comprometida (use 2FA), a conta do dono comprometida, o acesso do provedor do VPS ao disco em uso e a expiração da chave do Tailscale, se ficar ligada.

in the code:no código: pskit/bridge.py · pskit/device/bridge_push.py · pskit/runtime

Every AI session lands in one inboxToda sessão de IA chega numa única inbox

Every working conversation with an AI assistant (Claude Code, Codex or Grok) is saved as a file. The kit gathers these files from the laptop and from the server itself into one place, for the second brain to read. The brain never reads anyone's personal folder, and if a device stops sending, you hear about it within three days, not weeks later.

Cada conversa de trabalho com um assistente de IA (Claude Code, Codex ou Grok) fica guardada num arquivo. O kit junta esses arquivos do notebook e do próprio servidor num único lugar, para o second brain ler. O brain nunca lê a pasta pessoal de ninguém, e se um aparelho parar de enviar, você fica sabendo em até três dias, não semanas depois.

Laptop agent session folderspastas de sessão dos agentes Claude Code ~/.claude/projects/ Codex ~/.codex/sessions/ Grok ~/.grok/sessions/ bridge-push every 15 minutesa cada 15 minutos only new tailssó o final novo ≤ 256 MiB per run≤ 256 MiB por envio bridge keychave da ponte via tailnetpela tailnet ServerServidor bridge-receive paths and headers validatedcaminhos e cabeçalhos validados ≤ 5000 files, ≤ 2 GiB per run≤ 5000 arquivos, ≤ 2 GiB por vez atomic writes, own folderescrita atômica, pasta própria local bridgeponte local the server's own sessionsas sessões do próprio servidor every 15 minutesa cada 15 minutos Brain inboxInbox do brain inbox/sessions/ <laptop>/ claude · codex · grok + delivery receipt+ recibo de entrega <server>/<servidor>/ claude · codex · grok copied, not linkedcopiado, não linkado
Laptop agent session folderspastas de sessão dos agentes Claude Code ~/.claude/projects/ Codex ~/.codex/sessions/ Grok ~/.grok/sessions/ bridge-push every 15 minutesa cada 15 minutos only new tailssó o final novo ≤ 256 MiB per run≤ 256 MiB por envio ServerServidor bridge keychave da ponte via tailnetpela tailnet bridge-receive paths and headers validatedcaminhos e cabeçalhos validados ≤ 5000 files, ≤ 2 GiB per run≤ 5000 arquivos, ≤ 2 GiB por vez atomic writes, own folderescrita atômica, pasta própria local bridgeponte local the server's own sessionsas sessões do próprio servidor every 15 minutesa cada 15 minutos Brain inboxInbox do brain inbox/sessions/ <laptop>/ claude · codex · grok + delivery receipt+ recibo de entrega <server>/<servidor>/ claude · codex · grok copied, not linkedcopiado, não linkado

Technical detailDetalhe técnico

<brain_home>/inbox/sessions/ ├── macbook/ # a paired laptop# um laptop pareado │ ├── claude/projects/<project>/<session>.jsonl │ ├── codex/sessions/2026/09/22/rollout-*.jsonl │ ├── grok/sessions/%2F<project>/<uuid>/<file> │ └── .pskit-delivery.json {"finished", "files", "bytes"} └── myserver/ # the server's own sessions# as sessões do próprio servidor ├── claude/projects/... └── codex/sessions/...
  • Its own small protocol over SSH, not rsync: macOS ships a different rsync, and an rsync key could write anywhere the owner can.Um protocolo próprio e pequeno sobre SSH, não rsync: o macOS traz outro rsync, e uma chave de rsync escreveria em qualquer lugar que o dono pode.
  • Session files only grow, so only the new tail travels, checked against a hash of the last 4 KiB already delivered. A rewritten file is sent whole.Arquivos de sessão só crescem, então só o final novo viaja, conferido contra um hash dos últimos 4 KiB já entregues. Um arquivo reescrito vai inteiro.
  • The host never deletes a session file; the brain keeps its own cursor.O host nunca apaga um arquivo de sessão; o brain mantém o próprio cursor.
  • Each device leaves a receipt. Three days without one shows up in the daily summary.Cada dispositivo deixa um recibo. Três dias sem recibo aparecem no resumo diário.
  • The server's own sessions are copied, because agents create them readable only by the owner.As sessões do próprio servidor são copiadas, porque os agentes as criam legíveis só pelo dono.
in the code:no código: pskit/budget.py · pskit/alerts.py · pskit/notify.py · pskit/runtime

Running by itself, and telling you only what mattersRodando sozinho, e avisando só o que importa

Once installed, the server keeps its own memory in order, cleans up after agents, backs itself up, proves the backup works, and reaches your phone when something needs you.

Depois de instalado, o servidor mantém a própria memória em ordem, limpa o que os agentes deixam para trás, faz o próprio backup, prova que o backup funciona e chega no seu celular quando algo precisa de você.

Memory: the limits always fit in the machine

Memória: os limites sempre cabem na máquina

real output of budget.pysaída real do budget.py
Machine RAMRAM da máquina
10 GiBbrain
14.25 GiByour sessionssuas sessões
4 GiBCI
3.75 GiBmarginmargem
032 GiB
Group (slice)Grupo (slice) ProtectedProtegido Slowed fromFreado a partir de Hard ceilingTeto duro
brain pskit-brain.slice4 GiB8 GiB10 GiB
your sessionssuas sessões user-UID.slice012.25 GiB14.25 GiB
CI pskit-ci.slice03 GiB4 GiB
systemsistema system.slice2 GiB--
Under memory pressureSob pressão de memória

A guard checks every 30 seconds; six bad checks in a row freeze the brain and CI (never kill them), two good ones thaw them, and no freeze lasts more than 30 minutes.

Um guarda verifica a cada 30 segundos; seis verificações ruins seguidas congelam o brain e o CI (nunca matam), duas boas descongelam, e nenhum congelamento passa de 30 minutos.

Alerts: one message per change, not per check

Alertas: uma mensagem por mudança, não por verificação

60% 70% 80% 90% 100% critical 90crítico 90 clears < 85sai < 85 warn 80aviso 80 clears < 75sai < 75 disk usage, example curveuso de disco, curva de exemplo Naive ruleRegra ingênua The kitO kit warnaviso criticalcrítico back to warnvolta a aviso clearedresolvido 6 messages6 mensagens
disk usage, example curveuso de disco, curva de exemplo 60% 70% 80% 90% 100% warnaviso criticalcrítico back to warnvolta a aviso clearedresolvido Naive ruleRegra ingênua 6 messages6 mensagens The kitO kit critical 90 · clears below 85crítico 90 · sai abaixo de 85 warn 80 · clears below 75aviso 80 · sai abaixo de 75

Illustration on an example curve. The kit's lane follows the real rule in alerts.py: a level starts at its threshold and ends only 5 points below it. A naive rule, with no margin and a key that changes with the level, sends a new alert every time usage crosses 80%.

Ilustração numa curva de exemplo. A linha do kit segue a regra real do alerts.py: um nível começa no limite e só termina 5 pontos abaixo dele. Uma regra ingênua, sem margem e com a chave mudando junto com o nível, manda um alerta novo toda vez que o uso cruza os 80%.

criticalnowna hora

The private network is down, SSH is not listening, the firewall is off, disk above 90%.

A rede privada caiu, o SSH não está escutando, o firewall está desligado, disco acima de 90%.

warnnowna hora

A failed unit, a stale backup, the brain not answering, disk above 80%. Reminded once a day while it lasts.

Uma unit com falha, backup atrasado, o brain sem responder, disco acima de 80%. Lembrado uma vez por dia enquanto durar.

info19:00 summaryresumo das 19:00

Open problems, disk use, the last backup, a pending reboot, agent history sizes and devices silent for 3 days. One message a day.

Problemas abertos, uso de disco, último backup, reboot pendente, tamanho dos históricos dos agentes e dispositivos em silêncio há 3 dias. Uma mensagem por dia.

Anyone in the pskit group, including the brain, alerts with pskit notify warn "title" --key K. The message goes into a spool; only root delivers it, so the Telegram token or ntfy topic never leaves the root-only secrets folder.

Qualquer membro do grupo pskit, inclusive o brain, alerta com pskit notify warn "título" --key K. A mensagem vai para um spool; só o root entrega, então o token do Telegram ou o tópico do ntfy nunca sai da pasta de segredos do root.

A day on the server

Um dia no servidor

default times, changeablehorários padrão, ajustáveis
00 03 06 09 12 15 18 21 24 h in the owner'sno fuso time zonedo dono backup restore testteste de restore cache summaryresumo retrynova tentativa brain brain
00 03 06 09 12 15 18 21 24 h in the owner'sno fuso time zonedo dono backup restoreteste de testrestore cache summaryresumo retrynova tentativa brain brain

Outer dotted ring: every 5 minutes. Inner ring: every 15 minutes. Hollow marks: weekly or only when needed.

Anel pontilhado externo: a cada 5 minutos. Anel interno: a cada 15 minutos. Marcas vazadas: semanal ou só quando preciso.

  • Every dayTodo dia
  • 01:15

    Encrypted backup

    Backup criptografado

    restic keeps 7 daily, 4 weekly and 6 monthly snapshots; old data pruned on Sundays.

    O restic mantém 7 snapshots diários, 4 semanais e 6 mensais; dados antigos podados aos domingos.

  • 16:30

    Cache cleanup

    Limpeza de cache

    Conservative pip and npm cache maintenance.

    Manutenção conservadora dos caches de pip e npm.

  • 19:00

    Daily summary

    Resumo diário

    Everything that did not deserve an interruption.

    Tudo o que não merecia uma interrupção.

  • 19:30if neededse preciso

    Backup retry

    Nova tentativa de backup

    Only when there has been no success for 18 hours.

    Só quando não há sucesso há 18 horas.

  • Every SundayTodo domingo
  • 04:30

    Restore test

    Teste de restauração

    Restores a sample and compares it by hash, under the heavy-job lock.

    Restaura uma amostra e compara por hash, sob a trava de jobs pesados.

  • All the timeO tempo todo
  • 30 s

    Pressure guard

    Guarda de pressão

    Freezes brain and CI when the machine stops responding.

    Congela brain e CI quando a máquina para de responder.

  • 5 min

    Health check and heartbeat

    Verificação de saúde e heartbeat

    Disk, memory, network, units, backup age, brain health; a ping to the outside watcher.

    Disco, memória, rede, units, idade do backup, saúde do brain; um ping para o vigia externo.

  • 15 min

    Reaper and session delivery

    Reaper e entrega de sessões

    Ends headless browsers older than 3 h and idle dev servers older than 12 h.

    Encerra navegadores headless com mais de 3 h e dev servers ociosos com mais de 12 h.

  • Teal on the dialVerde-azulado no relógio
  • 05:0012:00

    Brain jobs, from its manifest

    Jobs do brain, do manifesto

    Times from the example manifest; the brain chooses its own.

    Horários do manifesto de exemplo; o brain escolhe os seus.

Day to day

No dia a dia

on the server, or from the laptop with ssh <server>no servidor, ou do laptop com ssh <servidor>
LookOlhar
  • pskit statusshort summaryresumo curto
  • pskit doctorevery check in plain languagetodas as verificações em linguagem simples
  • pskit doctor --bundlediagnostic file, no secretsarquivo de diagnóstico, sem segredos
  • pskit doctor --auditread-only, on any Ubuntu machinesó leitura, em qualquer Ubuntu
DevicesDispositivos
  • sudo pskit pair-serveaccept one more laptopaceitar mais um laptop
  • sudo pskit forget-device NAMErevoke a lost or replaced laptoprevogar um laptop perdido ou trocado
  • ./install.shon the laptop: choose 'connect it to a server'no laptop: escolha 'conectar a um servidor'
Brain
  • sudo pskit brain validate FILEcheck a manifestconferir um manifesto
  • sudo pskit brain apply FILEinstall its servicesinstalar os serviços dele
  • pskit notify SEV TITLEalert the owneralertar o dono
Backup
  • sudo pskit backup runback up nowfazer backup agora
  • sudo pskit backup restore-testprove a restore nowprovar uma restauração agora
  • sudo pskit backup snapshotslist what is storedlistar o que está guardado
ProofProva
  • sudo pskit provereboot proof on demandprova de reboot quando quiser
  • pskit prove --statuslast proof resultresultado da última prova
LeaveSair
  • sudo pskit uninstallundo everything from the ledger; data keptdesfaz tudo pelo ledger; dados mantidos
in the code:no código: tests/ · tests/e2e/run.sh · .github/workflows/ci.yml · docs/TESTING.md

What is proven, and what is not yetO que está provado, e o que ainda não está

What the kit promises was checked in four ways: automated tests, a full install on a throwaway test machine, a real run the way a person would do it, and reviews by a different AI model. Whoever built it did not check their own work, and what is not proven yet is listed just as plainly.

O que o kit promete foi conferido de quatro jeitos: testes automáticos, uma instalação completa numa máquina de teste descartável, uma execução de verdade como uma pessoa faria e revisões feitas por outro modelo de IA. Quem construiu não conferiu o próprio trabalho, e o que ainda não foi provado está listado com a mesma clareza.

202unit teststestes unitários

Every step against a temporary root

Cada passo contra uma raiz temporária

A scripted command runner stands in for the system; pairing runs over real HTTP on loopback; both languages must have every message.

Um executor de comandos roteirizado faz o papel do sistema; o pareamento roda por HTTP real no loopback; as duas línguas precisam ter todas as mensagens.

passingpassando
4linterslinters

ruff · mypy · shellcheck · text checkchecagem de texto

Plus Python 3.9 in the matrix, because that is what macOS ships.

Mais o Python 3.9 na matriz, porque é o que o macOS traz.

cleanlimpo
67/67end-to-end checksverificações ponta a ponta

The real install, as root, on a throwaway VM

A instalação real, como root, numa VM descartável

Packages, slices with real ceilings, firewall and key-only SSH, a restic backup and restore test, a fake brain from a manifest, a second user paired as the laptop over real SSH, a second run that changes nothing, and uninstall.

Pacotes, slices com tetos reais, firewall e SSH só com chave, backup e teste de restauração com restic, um brain falso a partir de um manifesto, um segundo usuário pareado como laptop por SSH real, uma segunda execução que não muda nada e a desinstalação.

GitHub Actions
15/15checks after a real rebootverificações após reboot real

The whole flow on real virtual machines

O fluxo inteiro em máquinas virtuais reais

One server and two laptops from the Ubuntu cloud image, run as a person would: real Tailscale, Telegram alerts, an SFTP backup to another machine with the restore test, two pairings, the lockdown checked from outside.

Um servidor e dois laptops a partir da imagem cloud do Ubuntu, rodados como uma pessoa rodaria: Tailscale real, alertas no Telegram, backup por SFTP para outra máquina com o teste de restauração, dois pareamentos, o lockdown conferido de fora.

real VMsVMs reais

Every defect found, every defect fixed

Cada defeito achado, cada defeito corrigido

one square per findingum quadrado por achado
Round 1Rodada 1a different model, fresh context, adversarialoutro modelo, contexto novo, adversarial
21 fixed21 corrigidos
Round 2Rodada 2a new pass verifying the fixesuma nova passada verificando as correções
9 new, fixed9 novos, corrigidos
End to endPonta a pontafound by the CI run on a throwaway VMachados pela execução no CI, numa VM descartável
2 fixed2 corrigidos
Real VMsVMs reaisa person's run: one server, two laptopsa execução de uma pessoa: um servidor, dois laptops
11 fixed11 corrigidos
Round 3Rodada 3a different model reviewing those fixesoutro modelo revisando essas correções
2 new, fixed2 novos, corrigidos
high severity or new defectalta severidade ou defeito novo medium or low / partial fixmédia ou baixa / correção parcial fix confirmedcorreção confirmada

Each fix counted only after a new test was shown to fail on the previous code. Examples from round 1: uninstall could restore an old /etc/fstab over later edits; the lockdown's undo was armed after the changes; root followed symlinks in the alert spool. The VM also caught the /run/sshd reboot defect behind the SSH rule. The real VM run caught the worst one: on a server up for more than ten minutes, the lockdown undid itself seconds after it was applied.

Cada correção só contou depois que um teste novo falhou no código anterior. Exemplos da rodada 1: a desinstalação podia restaurar um /etc/fstab antigo por cima de edições posteriores; o desfazer do lockdown era armado depois das mudanças; o root seguia symlinks no spool de alertas. A VM também detectou o defeito do /run/sshd no reboot, o que está por trás da regra de SSH. A rodada em VMs reais pegou o pior deles: num servidor ligado havia mais de dez minutos, o lockdown se desfazia segundos depois de aplicado.

Not proven yet

Ainda não provado

and how each gap closese como cada lacuna fecha
GapLacunaWhyPor quêHow it closesComo fecha
A rented VPSUm VPS alugadoThe real run used plain virtual machines; a provider's image, network and console were not exercisedA execução real usou máquinas virtuais simples; imagem, rede e console de um provedor não foram exercitadosOne install on a small hourly VPSUma instalação num VPS pequeno por hora
Real Tailscale in CITailscale real no CICI skips it and pairs over loopback; the real VM run covered it by handO CI pula e pareia pelo loopback; a execução em VMs reais cobriu à mãoAn auth key stored as a CI secretUma auth key guardada como segredo do CI
Laptop side on macOSLado do laptop no macOSlaunchd agents and macOS openssh are unit tested only; the Linux laptop side ran for realAgentes launchd e o openssh do macOS só têm teste unitário; o lado do laptop Linux rodou de verdadeThe first real pairing from a MacO primeiro pareamento real a partir de um Mac
ntfy deliveryEntrega por ntfyCovered with fake HTTP endpoints; Telegram ran for realCoberta com endpoints HTTP falsos; o Telegram rodou de verdadeThe first real install with ntfyA primeira instalação real com ntfy
Long-running behaviorComportamento de longo prazoReminders, weekly restore tests, freezes under real loadLembretes, testes de restauração semanais, congelamentos sob carga realWeeks of real useSemanas de uso real

Words used on this pagePalavras usadas nesta página

Each term in a sentence or two, in plain words.

Cada termo em uma ou duas frases, em palavras simples.

The machineA máquina

Server
Servidor
A computer that stays on and works for you, even when you are not using it.
Um computador que fica ligado trabalhando para você, mesmo quando você não está usando.
VPS
A server you rent by the month from a hosting provider: on its website you pick a size, choose Ubuntu 24.04 and receive an address and a login.
Um servidor alugado por mês de um provedor: no site dele você escolhe o tamanho, marca Ubuntu 24.04 e recebe um endereço e um acesso.
Linux
The family of free operating systems most servers run. Ubuntu is one of them.
A família de sistemas operacionais gratuitos que a maioria dos servidores usa. O Ubuntu é um deles.
Ubuntu
A free Linux operating system, widely used on servers. The kit needs version 24.04.
Um sistema operacional Linux gratuito, muito usado em servidores. O kit pede a versão 24.04.
Terminal
The window where you type text commands. Here you only paste the install line.
A janela onde se digitam comandos em texto. Aqui você só cola a linha de instalação.
Reboot
Restarting the machine. The kit ends with one to prove everything comes back by itself.
Reiniciar a máquina. O kit termina com um para provar que tudo volta sozinho.

Getting inComo se entra

Shell
The program inside the terminal that reads your commands. Shell access means being able to run any command.
O programa dentro do terminal que lê os seus comandos. Ter acesso ao shell é poder rodar qualquer comando.
root and sudo
root e sudo
root is the all-powerful administrator account of a Linux machine; sudo lets your own user act as root for one command, after asking your password.
root é a conta de administrador com poder total numa máquina Linux; o sudo deixa o seu usuário agir como root num comando, depois de pedir a sua senha.
SSH
The secure way to reach a server's terminal from another computer. The kit accepts keys only, never passwords.
O jeito seguro de chegar ao terminal de um servidor a partir de outro computador. O kit só aceita chaves, nunca senha.
Key
Chave
A small file on your laptop that works like a door key and takes the place of a password.
Um arquivo pequeno no seu notebook que funciona como a chave de uma porta e substitui a senha.
Port
Porta
A numbered door on a machine, one per service, like the apartment numbers in a building.
Uma porta numerada na máquina, uma para cada serviço, como os números dos apartamentos num prédio.
Tailscale
A private network that links your devices as if they were in the same house, without opening the server to the internet. Your own Tailscale network is called a tailnet.
Uma rede privada que liga seus aparelhos como se estivessem na mesma casa, sem abrir o servidor para a internet. A sua rede no Tailscale se chama tailnet.

Protection and backupProteção e backup

Firewall
A doorman that decides who may reach the machine. Here, only your private network.
Um porteiro que decide quem pode chegar à máquina. Aqui, só a sua rede privada.
2FA
Two-step login: besides the password, a code from your phone. Worth turning on for your Tailscale account.
Login em duas etapas: além da senha, um código do celular. Vale ligar na sua conta do Tailscale.
Encrypted backup
Backup criptografado
A copy of your data, locked with a password only you have and kept somewhere else.
Uma cópia dos seus dados, trancada com uma senha que só você tem e guardada em outro lugar.
S3
A common standard for storing files in the cloud. Many providers offer storage that works with it, such as Backblaze B2, Wasabi or Hetzner.
Um padrão comum para guardar arquivos na nuvem. Vários provedores oferecem armazenamento compatível, como Backblaze B2, Wasabi ou Hetzner.
restic
The backup program the kit uses. It encrypts the copy and the kit checks every week that it can be restored.
O programa de backup que o kit usa. Ele criptografa a cópia, e o kit confere toda semana se ela pode ser restaurada.
Hash
A short fingerprint of a file. Two files with the same hash are the same file.
Uma impressão digital curta de um arquivo. Dois arquivos com o mesmo hash são iguais.

Alerts, AI and the second brainAvisos, IA e o second brain

ntfy
A free phone app that shows the notifications your server sends. No account needed.
Um app gratuito de celular que mostra os avisos que o seu servidor manda. Não precisa de conta.
AI session
Sessão de IA
One working conversation with an assistant such as Claude Code or Codex, saved as a file.
Uma conversa de trabalho com um assistente como Claude Code ou Codex, guardada num arquivo.
Second brain
A system that organizes your notes and AI sessions so you can search them later. It runs on top of this kit, in a place set aside for it.
Um sistema que organiza suas notas e sessões de IA para você consultar depois. Ele roda em cima deste kit, num lugar reservado para ele.
Manifest
Manifesto
The list in which the second brain declares what it needs: services, schedules, memory and backup.
A lista em que o second brain declara o que precisa: serviços, horários, memória e backup.
Slice
A group of programs with its own memory limit. The kit keeps one for the second brain, one for your sessions and one for CI.
Um grupo de programas com limite de memória próprio. O kit mantém um para o second brain, um para as suas sessões e um para o CI.
CI
Continuous integration: automated tests that run on every code change. The kit can host the machines that run them, as an optional module.
Integração contínua: testes automáticos que rodam a cada mudança no código. O kit pode hospedar as máquinas que rodam esses testes, como módulo opcional.

For engineersPara quem é técnico

The rest of the page is for people who want to build on the kit: the written contract between the server and the second brain, and what is inside the repository.

O restante da página é para quem quer construir em cima do kit: o contrato escrito entre o servidor e o second brain, e o que tem dentro do repositório.

docs/HOST-BRAIN-CONTRACT.md · pskit/manifest.py · pskit/brainslot.py

Two layers, one written contractDuas camadas, um contrato escrito

The host never reaches into the brain, and the brain never configures the machine. Each side can change anything behind its half; changing the contract needs both. Most breakages happen where the two get mixed.

O host nunca mexe no interior do brain, e o brain nunca configura a máquina. Cada lado pode mudar o que quiser da sua metade; mudar o contrato exige os dois. A maioria das quebras acontece onde os dois se misturam.

The host gives the brain

O host dá ao brain

  1. An identity: user and group pskit-brain; the owner is in the group and reads everything.Uma identidade: usuário e grupo pskit-brain; o dono está no grupo e lê tudo.
  2. A home: brain_home, the only place the brain writes; disk use watched.Uma casa: brain_home, o único lugar onde o brain escreve; uso de disco vigiado.
  3. A memory reservation: its own slice, sized from its declared peak.Uma reserva de memória: slice própria, dimensionada pelo pico declarado.
  4. A heavy-job lock, shared with the backup, so the two never peak together.Uma trava de jobs pesados, compartilhada com o backup, para os dois nunca pesarem juntos.
  5. Scheduling: the host turns each declared service into a hardened unit.Agendamento: o host transforma cada serviço declarado numa unit protegida.
  6. A private port on loopback, reachable from the laptop only by the tunnel key.Uma porta privada no loopback, que o laptop só alcança pela chave do túnel.
  7. Session delivery from every device into one inbox.Entrega de sessões de todos os dispositivos numa única inbox.
  8. Backup of the paths the brain lists, with a weekly restore test.Backup dos caminhos que o brain lista, com teste de restauração semanal.
  9. Alerts through pskit notify, without ever seeing the channel's credential.Alertas via pskit notify, sem nunca ver a credencial do canal.
  10. Health polling every 5 minutes, alerting once when it fails.Verificação de saúde a cada 5 minutos, alertando uma vez quando falha.
/etc/pskit/host.jsonby the host · no secretsdo host · sem segredos
{
  "contract_version": 0,
  "language": "en",
  "scenario": "linux-server",
  "machine_name": "myserver",
  "brain_home": "/srv/myserver/brain",
  "brain_user": "pskit-brain",
  "brain_port": 8799,
  "session_inbox": "inbox/sessions",
  "memory_budget": { "brain_max": 10.0, ... },
  "notify_command": "/usr/local/bin/pskit notify",
  "heavy_lock": "/run/pskit/heavy.lock"
}
What the host does with peak_memoryO que o host faz com o peak_memory
2048+3072 MiB=5 GiB×1.25=6.25 GiB ceilingteto de 6,25 GiB
protected 2.5protegido 2,5 slowed from 5freado a partir de 5 hard stop 6.25 GiBlimite duro 6,25 GiB

Never below 1 GiB, never above a third of RAM. With no manifest yet, the brain gets 31.9% of RAM, rounded down in 256 MiB steps: 10 GiB on a 32 GiB machine.

Nunca abaixo de 1 GiB, nunca acima de um terço da RAM. Sem manifesto, o brain recebe 31,9% da RAM, arredondado para baixo em passos de 256 MiB: 10 GiB numa máquina de 32 GiB.

The brain gives the host

O brain dá ao host

  • services[]resident (always on, restarted) or scheduled; absolute command; optional heavy lock and timeoutresidente (sempre ligado, reiniciado) ou agendado; comando absoluto; trava pesada e timeout opcionais
  • scheduleevery N minutes, daily at HH:MM, or weeklya cada N minutos, diário às HH:MM ou semanal
  • healtha loopback URL whose JSON says status okuma URL de loopback cujo JSON diz status ok
  • backupwhat to include and exclude inside its homeo que incluir e excluir dentro da sua casa
  • peak_memorymeasured resident and batch peakspicos medidos, residente e de lote
  • e2e_testa command that proves the brain works; run during the final proofum comando que prova que o brain funciona; roda na prova final
  • environmentplain settings, never secretsconfigurações simples, nunca segredos
manifest.jsondeclared by the braindeclarado pelo brain
{
  "manifest_version": 0,
  "name": "example-brain",
  "services": [
    { "name": "query", "kind": "resident" },
    { "name": "capture", "kind": "scheduled",
      "schedule": { "daily_at": ["05:00", "12:00"] },
      "heavy_lock": true }
  ],
  "health": { "url": "http://127.0.0.1:8799/health" },
  "backup": { "include": ["vault", "state"],
              "exclude": ["index", "models"] },
  "peak_memory": { "resident_mib": 2048,
                   "batch_mib": 3072 },
  "e2e_test": { "command": [...] }
}
And it promisesE promete
  • to write only inside its homeescrever só dentro da sua casa
  • to listen only on loopbackescutar só no loopback
  • to report failure through pskit notify, never silentlyavisar falhas por pskit notify, nunca em silêncio

sudo pskit brain validate FILE
sudo pskit brain apply FILE

github.com/ogabrielalonso/personal-server-kit · public

Inside the repositoryPor dentro do repositório

Python standard library only, 3.9 or newer, so nothing has to be installed before the installer. About 8,100 lines of code, 36 installed templates and 385 messages in each language.

Só a biblioteca padrão do Python, 3.9 ou mais novo, para nada precisar ser instalado antes do instalador. Cerca de 8.100 linhas de código, 36 templates instalados e 385 mensagens em cada idioma.

personal-server-kit/ ├── install.sh # finds Python, gets the code# acha o Python, baixa o código ├── pskit/ │ ├── install.py # the guided installer# o instalador guiado │ ├── linux/ # server steps# passos do servidor │ ├── device/ # laptop: pairing, tunnel# laptop: pareamento, túnel │ ├── server/ # pairing server, keys# servidor de pareamento, chaves │ ├── runtime/ # health, backup, guards# saúde, backup, guardas │ ├── templates/ # units, tmpfiles, sshd# units, tmpfiles, sshd │ └── locales/ en.json · pt.json ├── examples/ # brain manifest, answers# manifesto do brain, respostas ├── tests/ # 202 unit · e2e/run.sh# 202 unitários · e2e/run.sh └── docs/ # the 8 documents# os 8 documentos
INSTALLER

The flow, every step, unattended installs.

O fluxo, cada passo, instalação sem interação.

OPERATIONS

Daily life, updates, devices, restoring from backup.

O dia a dia, atualizações, dispositivos, restaurar do backup.

TROUBLESHOOTING

What to do when something fails.

O que fazer quando algo falha.

SECURITY

Threat model and every protection.

Modelo de ameaças e cada proteção.

HOST-BRAIN-CONTRACT

The interface for the brain layer.

A interface para a camada do brain.

STRUCTURE

The host layout, component by component, and why each piece exists.

O layout do host, componente por componente, e por que cada peça existe.

DECISIONS

What was decided and why; what is still open.

O que foi decidido e por quê; o que segue aberto.

TESTING

What is proven, where, and what is not yet.

O que está provado, onde, e o que ainda não está.

Decisions

Decisões

six decided, one provisional, one waiting on the authorseis decididas, uma provisória, uma aguardando o autor
D1Machines without LVM get directories on the existing disk, with disk alerts. A running machine's root disk cannot be repartitioned by an installer.Máquinas sem LVM recebem pastas no disco existente, com alertas de disco. Um instalador não reparticiona o disco raiz de uma máquina em uso.decideddecidido
D2One SSH channel, filtered by the firewall. Binding sshd to the tailnet address is a known cause of SSH not coming back after a reboot.Um canal SSH, filtrado pelo firewall. Prender o sshd ao endereço da tailnet é uma causa conhecida de o SSH não voltar depois de um reboot.decideddecidido
D3Backup to S3-compatible storage first, another owned machine second, a local disk with a warning third. Never a laptop by default.Backup em armazenamento compatível com S3 primeiro, outra máquina própria em segundo, disco local com aviso em terceiro. Nunca um laptop por padrão.decideddecidido
D4Default alert channel. Implemented with Telegram as the default and ntfy as the alternative; the final default is the author's call.Canal padrão de alertas. Implementado com Telegram como padrão e ntfy como alternativa; o padrão final é decisão do autor.author's calldecisão do autor
D5Minimum hardware: refuse below about 4 GiB of RAM or 10 GiB of free disk, warn below 8 and 30. To revisit with the brain's measured peaks.Hardware mínimo: recusa abaixo de cerca de 4 GiB de RAM ou 10 GiB de disco livre, avisa abaixo de 8 e 30. A revisar com os picos medidos do brain.provisionalprovisório
D6Agent histories that fill the disk are reported in the daily summary, never moved or deleted.Históricos de agentes que enchem o disco aparecem no resumo diário, nunca são movidos nem apagados.decideddecidido
D7Name, license, public or private. Name personal-server-kit, command pskit, public repository under the PolyForm Noncommercial 1.0.0 license.Nome, licença, público ou privado. Nome personal-server-kit, comando pskit, repositório público sob a licença PolyForm Noncommercial 1.0.0.decideddecidido
D8Which systems can be the server. Linux only (Ubuntu 24.04): macOS cannot enforce memory limits and FileVault blocks an unattended boot. A Mac stays supported as the owner's laptop.Quais sistemas podem ser o servidor. Só Linux (Ubuntu 24.04): o macOS não garante limite de memória e o FileVault impede o boot sem ninguém. O Mac continua suportado como laptop do dono.decideddecidido