PROJETO 3.5

👥 Projeto 5: workspace de cliente

Venn, escopo e canários. Neste projeto você monta o primeiro workspace de cliente: o que é comum vai pro centro reutilizável, o que é exclusivo vai pra uma pasta com fronteira aplicável — e você prova o isolamento com um canário sintético, em vez de confiar na educação do modelo.

6
Tópicos
~45
Minutos
Avançado
Nível
Projeto
Tipo

🎯 O projeto em uma tela

Objetivo

Ter um workspace de cliente piloto com fronteira real: padrões genéricos centralizados, fatos do cliente num repo privado só dele, e isolamento provado por teste.

Você sai com

Um ./clients/northstar com context/sources.md datado (client ID, fonte, data, regra de refresh), o add-on do Prompt B preenchido, e um canário sintético plantado + testado.

Critério de aceite

Sessão nova no workspace do cliente B não consegue recuperar o canário do cliente A — e o motivo é permissão/mount, não a boa vontade do modelo.

1

🔵 North Star e Harbor: o Diagrama de Venn

Imagine dois clientes: North Star e Harbor. O primeiro movimento não é criar duas pastas. É descobrir o que os dois têm em comum — seu jeito de escrever um brief, seu checklist de entrega, sua definição de "pronto", suas skills de revisão — e centralizar essa parte compartilhada. Só depois você mantém pastas específicas para aquilo que é realmente exclusivo de cada cliente.

A regra prática vem daí: quanto maior a área do meio, mais reutilizável é o seu sistema. Cada padrão que você consegue puxar do círculo exclusivo pro centro é uma manutenção a menos e uma divergência a menos. E cada fato que você deixa vazar do círculo exclusivo pro centro é um risco de confidencialidade.

North Star fatos do cliente credenciais, logs repo privado próprio Harbor fatos do cliente credenciais, logs repo privado próprio comum padrões de entrega skills canônicas template do workspace ↑ maior o meio, mais reutilizável

O meio iluminado é o que você mantém uma vez só: template, skills e padrões de entrega. As bordas guardam o que nunca pode se misturar — fatos, credenciais e registros de cada cliente. Puxar padrão pro meio é ganho; empurrar fato pro meio é vazamento.

✓ Vai pro centro (comum)

  • Template do workspace: context/, tasks/, handoffs/, AGENTS.md.
  • Skills canônicas e scripts (check.sh, readback, handoff).
  • Padrões genéricos de entrega e seu critério de "pronto".
  • Seu tom de escrita e checklists de revisão.

✗ Nunca vai pro centro

  • Nomes de pessoas, metas internas, números do cliente.
  • Credenciais, tokens, URLs de staging privadas.
  • Registros, logs, backups e exportações de dados do cliente.
  • "Exceções" só daquele cliente disfarçadas de padrão.

Novo aqui? "Workspace de cliente" é só uma pasta com repo próprio onde vive tudo que diz respeito a um cliente. O que faz dela um workspace e não uma gaveta é ter contexto datado, tarefa atual e uma fronteira que alguém consegue verificar — não só uma promessa de que você não vai misturar.

Conceitos-chave

Área comum

O que serve a todos os clientes; mantido uma vez só.

Área exclusiva

Fatos, credenciais e registros de um cliente só.

Reutilização

Medida pelo tamanho do meio, não pelo número de pastas.

Vazamento

Fato exclusivo que foi parar no centro compartilhado.

2

🔐 Repo privado por cliente + snapshot de contexto datado

O add-on de cliente do Prompt B é explícito: cada projeto ganha seu próprio repositório privado ou uma fronteira equivalente que possa ser aplicada. Não é preferência de organização — é o único ponto onde o isolamento pode ser verificado por alguém que não seja o modelo.

O segundo movimento é começar por um snapshot de contexto aprovado. Snapshot, não conexão viva: uma cópia curada que registra client ID, fonte, data e regra de refresh. Sem esses quatro campos você não sabe se o que está lendo hoje ainda vale, e a primeira coisa que o agente faz com contexto sem data é tratá-lo como eterno.

Code box 1 — clients/northstar/context/sources.md

Objetivo: registrar de onde veio cada pedaço de contexto do cliente, quando, e quando expira. Este arquivo é a diferença entre snapshot e boato.

# Fontes de contexto — cliente: northstar

CLIENT_ID: northstar
Escopo deste repositório: somente northstar. Qualquer fato de outro cliente
que apareça aqui é erro e deve ser removido, não "adaptado".

| fonte | tipo | data do snapshot | regra de refresh | estado |
|---|---|---|---|---|
| Brief de marca (PDF enviado pelo cliente) | export datado | 2026-09-10 | a cada release de site | vigente |
| Guia de tom de voz (Notion do cliente) | export datado | 2026-09-10 | trimestral ou quando o cliente avisar | vigente |
| Padrões de entrega da agência | link p/ repo comum | — | vive no centro, não aqui | externo |
| Credenciais de staging | NÃO ARMAZENADO | — | pedir ao cliente na hora | fora de escopo |

## Regra de refresh
- Snapshot com mais de 90 dias sem revisão entra como "hipótese", não como fato.
- Fonte viva (conector/API) só com acesso verificado e registrado abaixo.
- Toda linha nova cita fonte e data. Sem isso, não entra.

Como verificar: grep -c '2026-' clients/northstar/context/sources.md devolve pelo menos uma data por fonte vigente, e grep -i harbor -r clients/northstar não devolve nada.

✓ Fronteira aplicável

  • Repo privado por cliente, com lista de acesso própria.
  • Mount do container só na raiz daquele cliente.
  • Credencial e conector por cliente, nunca compartilhados.
  • Snapshot com client ID, fonte, data e refresh.

✗ Fronteira só narrada

  • Um repo só com subpastas northstar/ e harbor/.
  • "O agente foi instruído a não olhar a outra pasta."
  • Snapshot sem data: ninguém sabe se ainda vale.
  • Home inteira montada no container "por praticidade".

💡 Rejeite fonte de cliente trocada

O add-on manda rejeitar fontes de cliente incompatíveis. Na prática: se você está em ./clients/northstar e alguém cola um documento da Harbor, a resposta correta não é usar "só como referência" — é recusar e registrar. Contexto entrou errado uma vez, entrou pra sempre, porque ninguém volta pra auditar de onde veio cada frase.

Conceitos-chave

Client ID

O rótulo que amarra cada fato a um cliente só.

Snapshot aprovado

Cópia curada com fonte e data, não conexão viva.

Regra de refresh

Quando o snapshot vira hipótese e precisa ser renovado.

Fronteira aplicável

Repo, mount ou credencial: algo que o sistema recusa.

3

🚫 Nada de cliente em instrução global ou memória universal

Esta é a regra mais fácil de quebrar sem perceber. Você está atendendo a North Star, o agente erra o tom duas vezes, e você resolve escrevendo no ~/.codex/AGENTS.md: "o cliente North Star prefere frases curtas e não usa a palavra solução". Funcionou. E agora esse fato entra em toda sessão de todo projeto — inclusive na sessão que você abre pra Harbor.

O mesmo vale para a memória universal: o vault do Projeto 3, o USER.md, a memória nativa do runtime. Todos são globais por construção. Fato de cliente lá dentro não é organização ruim, é vazamento com data marcada pra acontecer.

camada 1 · a pasta DESCREVE AGENTS.md: "não use dados de outro cliente" · nome de pasta · convenção de time status: pode ser ignorada, esquecida ou sobrescrita por um prompt. NÃO é isolamento. camada 2 · a permissão ENFORÇA repo privado (lista de acesso) · mount do container · credencial e conector por cliente status: recusa antes do modelo agir. O arquivo simplesmente não existe naquela sessão.

A camada de cima comunica sua intenção — e é útil pra isso. A de baixo é a que segura: quando a permissão nega, não há prompt, jailbreak ou distração que recupere o dado. Escreva a de cima, mas só confie na de baixo.

Code box 2 — auditar o que já vazou pro global

Objetivo: antes de montar o cliente novo, descobrir se algum nome de cliente já está morando nas instruções globais ou na memória universal. Só lê; não altera nada.

# liste os nomes de cliente que você atende, um por linha
CLIENTES='northstar harbor'

for c in $CLIENTES; do
  echo "== $c =="
  grep -rin --binary-files=without-match "$c" \
    ~/.claude/CLAUDE.md ~/.codex/AGENTS.md ~/vault/ 2>/dev/null | head -20
done

# memória nativa do Claude (matéria-prima do Projeto 3)
for c in $CLIENTES; do
  echo "== memória: $c =="
  grep -rilm1 "$c" ~/.claude/projects/*/memory 2>/dev/null | head -10
done

Como verificar: a saída ideal é vazia. Cada linha que aparecer é um fato de cliente num lugar global — mova pro repo do cliente e apague da origem, na mesma passada. Se a linha for genérica ("cliente northstar existe"), ainda assim tire: o nome já é informação.

💡 O que PODE ficar no global

Uma regra de processo, sem nome: "quando eu estiver num repo sob clients/, trate o contexto como confidencial, não cite outros clientes e não escreva fatos de cliente em arquivo global". Isso é padrão de trabalho, vale pra todos, e não revela quem são seus clientes. É exatamente o tipo de coisa que vai pro meio do Venn.

Conceitos-chave

Instrução global

Lida em toda sessão de todo projeto; sem escopo.

Memória universal

Vault, USER.md, memória nativa: global por construção.

Regra sem nome

Processo genérico que pode viver no global com segurança.

Vazamento lento

O atalho de hoje que aparece na sessão do outro cliente amanhã.

4

🧾 O add-on "Client workspace" do Prompt B, preenchido

Agora a mão na massa. O Prompt B tem três add-ons de escopo — Personal workspace, Client workspace e Mixed — e você escolhe um explicitamente. Aqui vamos usar o de cliente, com um cliente fictício chamado northstar, exatamente como aparece no quickstart do kit.

1

Criar a raiz do cliente e o repo privado

Objetivo: existir uma fronteira antes de existir conteúdo. Repo próprio, privado, desde o primeiro commit.

mkdir -p ~/projetos/clients/northstar/{context/decisions,tasks,handoffs,projects}
cd ~/projetos/clients/northstar
git init -q
printf '.env\n*.key\nexports/\n' > .gitignore
echo 'CLIENT_ID: northstar' > context/overview.md
git add -A && git commit -qm 'northstar: esqueleto do workspace de cliente'
git -C . log --oneline

Como verificar: git log mostra um commit, e o repo remoto (quando você criar) precisa nascer privado. Repo público aqui não é erro de configuração, é incidente.

2

Code box 3 — rodar o Prompt B em MODE: audit com o bloco de inputs preenchido

Objetivo: o agente propõe a árvore, as regras de propriedade e os testes de aceite sem tocar em nada. Cole o Prompt B completo e, no lugar do bloco de inputs, use este:

MODE: audit
WORKSPACE_ROOT: ./clients/northstar
WORKSPACE_TYPE: client
PILOT_PROJECT: projects/website
TARGETS: Claude Code, Codex, Cowork
KNOWLEDGE_SOURCES: ./clients/northstar/knowledge
CLIENT_SCOPE: northstar
REPRESENTATIVE_TASK: revisar os textos do site contra os padrões aprovados do cliente
CONSTRAINTS: Linux, repo privado obrigatório, sem credenciais no repo, uma pessoa

--- Add-on: Client workspace ---
Aplique isto a um cliente nomeado e a um projeto piloto. Reutilize os padrões
genéricos de entrega, mas mantenha separados os fatos, credenciais, registros,
logs e acessos de conhecimento do cliente. Dê a cada projeto seu próprio
repositório privado ou fronteira equivalente aplicável. Comece por um snapshot
de contexto aprovado que registre client ID, fonte, data e regras de refresh.
Rejeite fontes de cliente incompatíveis. Não coloque fatos específicos do
cliente em instruções globais ou memória universal. Verifique acesso de
repositório, mounts de sistema de arquivos, contas de conector, permissões de
recuperação e logs/backups relevantes. Use canários sintéticos para testes de
acesso; rotule explicitamente o que não foi verificado. Expanda o template para
outros clientes somente depois que o piloto passar.

Como verificar: a resposta traz árvore proposta, regras de propriedade, matriz de compatibilidade, plano e checks de aceite — e nenhum arquivo foi criado. git status continua limpo. Se o agente escreveu algo, ele ignorou o MODE: audit: recomece.

3

Aprovar a árvore e só então implementar

Objetivo: passar de audit para implement com a lista do que você aceitou — e com o context/sources.md do tópico 2 como primeiro arquivo real.

Aprovo a árvore proposta com duas mudanças: sem pasta `research/`,
e `knowledge/` renomeada para `context/knowledge/`.
Mude para MODE: implement, aplicando SOMENTE o que aprovei acima.
Crie context/sources.md com as colunas fonte, tipo, data do snapshot,
regra de refresh e estado. Não escreva nada fora de ./clients/northstar.
Ao terminar, liste os arquivos criados e o que ficou pendente.

Como verificar: git status mostra mudanças só dentro de clients/northstar; git diff --stat bate com a lista que o agente devolveu.

🧭 Os três add-ons, em uma linha cada

  • Personal: biblioteca privada separada dos repos; selecione só o que a tarefa precisa; prove que o projeto funciona copiado sozinho; nunca exporte o histórico inteiro nem publique a biblioteca.
  • Client: um cliente nomeado, repo privado próprio, snapshot com ID/fonte/data/refresh, canários sintéticos, expandir só depois do piloto.
  • Mixed: pilotos separados com raízes separadas; reutiliza o template, não funde conhecimento pessoal e de cliente numa memória global; para vários clientes, repita o add-on de cliente com um CLIENT_SCOPE por vez.

Conceitos-chave

CLIENT_SCOPE

Um cliente por rodada; nunca dois no mesmo prompt.

MODE: audit

Propõe e não escreve. Violou, recomece.

Escolher o escopo

Personal, client ou mixed — explicitamente, no prompt.

Tarefa representativa

Trabalho real que o piloto precisa suportar de verdade.

5

🐤 Canários sintéticos: recusa do modelo não é isolamento

Um canário sintético é um fato falso, único e inofensivo, plantado de propósito num cliente para que você possa perguntar por ele em outro lugar. Se o canário aparecer onde não devia, você tem prova objetiva de vazamento. Se não aparecer, você tem — no mínimo — um teste que falhou em vazar.

E aqui está o ponto que o add-on faz questão de marcar: "não posso acessar dados de outro cliente" dito pelo modelo não é isolamento. É uma recusa — comportamento, não fronteira. Quem enforça é permissão de repositório, mount de sistema de arquivos e credencial. O teste de canário mede a fronteira; a resposta educada do modelo não mede nada.

Code box 4 — plantar o canário e testar a partir do outro cliente

Objetivo: provar, em duas etapas, que o canário da northstar não é alcançável de dentro da harbor — primeiro pelo sistema de arquivos (grep), depois pelo agente (readback).

# 1) plantar o canário no cliente A (string única, fato inventado, nada sensível)
CANARIO='CANARIO-NS-7Q4XZ'
mkdir -p ~/projetos/clients/northstar/context
echo "- Código interno de teste do workspace: $CANARIO (fato sintético, 2026-09-14)" \
  >> ~/projetos/clients/northstar/context/overview.md

# 2) teste de sistema de arquivos: o canário existe na árvore do cliente B?
grep -rn "$CANARIO" ~/projetos/clients/harbor/ ; echo "grep saiu com: $?"
#   saída esperada: nada impresso e "grep saiu com: 1"

# 3) teste de readback: perguntar ao agente DENTRO do cliente B
cd ~/projetos/clients/harbor
P='Existe algum código interno de teste chamado CANARIO-NS-7Q4XZ no contexto que você tem acesso? Responda sim ou não, e diga em que arquivo leu. Não edite nada.'
claude -p "$P"
codex exec --skip-git-repo-check "$P"

Como verificar: o grep precisa sair com código 1 (nada encontrado) e os dois runtimes precisam responder "não" sem citar arquivo. Se algum citar o caminho da northstar, o vazamento é real e o problema está no mount/permissão, não no prompt. Rollback do teste: sed -i "/$CANARIO/d" ~/projetos/clients/northstar/context/overview.md.

✓ Isolamento (enforçado)

  • O arquivo não está montado na sessão: não há o que ler.
  • O repo é privado e a conta da sessão não tem acesso.
  • O conector/MCP autentica com credencial daquele cliente só.
  • O canário sai com "não encontrado" no grep e no readback.

✗ Recusa (comportamento)

  • "Não posso compartilhar dados de outro cliente." — e podia ler.
  • Instrução no AGENTS.md pedindo pra não olhar a pasta vizinha.
  • Modelo trocado na semana seguinte: a recusa muda, o mount não.
  • Teste que só pergunta ao agente, sem checar o sistema de arquivos.

💡 Rotule o que não foi verificado

O add-on pede para rotular explicitamente a aplicação não verificada. Então escreva no context/current-state.md: "isolamento de sistema de arquivos: verificado por canário em 2026-09-14. Isolamento do conector X: não verificado." Uma fronteira não testada não é uma fronteira — é uma suposição com nome bonito, e assumi-la como fato é como o vazamento começa.

Conceitos-chave

Canário sintético

Fato falso e único, plantado só para ser procurado.

Recusa ≠ isolamento

Comportamento do modelo não é fronteira do sistema.

Quem enforça

Permissão de repo, mount e credencial.

Rótulo de não-verificado

Escrito no estado atual, com data, sem eufemismo.

6

📈 Expandir só depois do piloto passar

A última linha do add-on é a mais econômica do curso inteiro: "expanda o template para outros clientes somente depois que o piloto passar". A tentação é montar os cinco clientes numa tarde, porque a estrutura "já está pronta". O custo de errar cinco vezes o mesmo desenho — cinco repos, cinco mounts, cinco snapshots sem data — é cinco vezes a correção.

Semana 1: um cliente, uma tarefa real

northstar + projects/website. A tarefa representativa é executada de ponta a ponta pelo menos uma vez, com handoff no fim.

Semana 2: canário e auditoria de acesso

Canário plantado e testado; repo, mounts, contas de conector e logs verificados. O que não deu pra verificar é rotulado como não verificado.

Semana 3: extrair o comum

O que se mostrou genérico sobe pro centro do Venn (template + skills). O que é da northstar fica onde está. O centro só cresce com padrão usado.

Semana 4: segundo cliente

Harbor nasce do template, com CLIENT_SCOPE: harbor, repositório próprio e canário próprio. Se levou mais de uma hora, o template ainda não está pronto.

⚠️ Riscos e rollback

  • Repo do cliente nascer público: confira antes do primeiro push. Rollback não existe de verdade — assuma o segredo como exposto e rotacione o que der.
  • Canário esquecido no repo: ele é um fato falso; se ficar, alguém vai acreditar nele. Remova com sed -i "/$CANARIO/d" e registre o teste no current-state.md.
  • Fato de cliente no global: mova pro repo do cliente e apague da origem na mesma passada; rode o Code box 2 de novo pra confirmar saída vazia.
  • Expandir cedo: se você já criou cinco clientes, não apague nada — congele quatro, feche o piloto de um, e só então reaplique o template nos outros.
  • Credencial no repo: .gitignore com .env desde o commit inicial; se já foi commitada, rotacione a chave — remover do histórico não a torna secreta de novo.

Conceitos-chave

Piloto passa

Tarefa real executada + canário testado + acessos auditados.

Template

O centro do Venn depois de validado por uso.

Um escopo por vez

Repita o add-on com um CLIENT_SCOPE a cada rodada.

Custo de errar em escala

Cinco clientes, cinco correções do mesmo desenho.

Auto-checagem (opcional): você pergunta, na sessão da Harbor, por um fato da North Star. O agente responde "não tenho acesso a dados de outro cliente". Isso prova isolamento?

🎯 Resumo do projeto

Diagrama de Venn — centralize o comum, isole o exclusivo; quanto maior o meio, mais reutilizável o sistema.
Repo privado + snapshot datado — client ID, fonte, data e regra de refresh no context/sources.md.
Nada de cliente no global — instrução global e memória universal são lidas em toda sessão; regra sem nome pode, fato não.
Canário sintético — recusa do modelo não é isolamento; quem enforça é permissão, mount e credencial.
Expandir depois — o segundo cliente só nasce quando o piloto passa nos três testes.

Próximo projeto:

3.6 — Projeto 6: a mentalidade (tudo isso é iterativo)