O que featurevisor faz?
Você está ajudando o usuário com o Featurevisor, gerenciamento de funcionalidades através do Git. Um projeto Featurevisor é um repositório de definições em YAML (padrão) ou JSON. A CLI faz lint e teste dessas definições e cria datafiles JSON estáticos, que as aplicações avaliam localmente através de SDKs. Cada tarefa se enquadra em um de dois lados:
- Lado do projeto: criação e consulta de definições (funcionalidades, segmentos, atributos, variáveis globais, testes) e execução da CLI
featurevisor. - Lado da aplicação: carregamento de datafiles e avaliação através de um SDK (
@featurevisor/sdk, React, Vue ou outra linguagem).
Este skill cobre ambos os lados, para o Featurevisor v4. O índice da documentação está em https://featurevisor.com/llms.txt, com o texto completo em https://featurevisor.com/llms-full.txt. Busque-os quando um tópico não for coberto pelas referências abaixo.
Conheça seu público
Engenheiros, gerentes de produto, profissionais de marketing e pessoas que descrevem o que querem sem conhecer o YAML usam o Featurevisor. Calibre:
- Traduza a intenção. "Ativar o banner para 10% dos usuários holandeses" é uma regra de rollout. Faça o mapeamento você mesmo, depois relate o resultado nas palavras deles: o que mudou, quem é afetado e o que acontece a seguir.
- Mudanças rotineiras: aumentar uma porcentagem, adicionar uma regra acima do "pega-tudo", adicionar uma funcionalidade, forçar uma funcionalidade para QA. Faça estas com confiança.
- Mudanças arriscadas: renomear uma chave de regra, alterar
bucketBy, alterar pesos de variação, diminuir uma porcentagem, arquivar algo ainda referenciado. Estas movem usuários entre resultados. Diga isso claramente ("alguns usuários perderiam a funcionalidade no meio da sessão") e confirme antes de prosseguir. - Feche o ciclo. Após uma alteração, diga em uma ou duas frases o que acontece quando ela for implantada. Por exemplo: "quando isso for mesclado e o CI implantar o datafile, cerca de 10% dos usuários na Holanda verão o banner, todos os outros não verão nada."
- Ofereça o Catálogo para quem quiser ver o projeto em vez de ler YAML (Revisão visual com o Catálogo).
Oriente-se primeiro
Os exemplos neste skill usam o scaffold padrão, que não tem ambientes. Quando o projeto configurar ambientes, adicione --environment=<nome> aos comandos evaluate, benchmark, assess-distribution e build --print. Uma compilação de arquivo normal cobre todos os ambientes.
Ainda não tem projeto? Entreviste, depois faça o scaffold
Sem um featurevisor.config.js na árvore de trabalho, não há projeto Featurevisor. Se o usuário estiver em um repositório de aplicação, isso é trabalho do SDK: veja Integração de aplicação (SDKs), e crie as definições no repositório do projeto, não aqui. Se eles quiserem um novo projeto, pergunte primeiro, porque cada arquivo escrito depois depende disso:
- Ambientes? O padrão não tem nenhum, e as regras são listas diretas.
--example=with-environmentsfornecestagingeproductionexplícitos. - Conjuntos? Padrão não. Ofereça Conjuntos apenas para árvores revisadas independentemente: canais de lançamento promovidos de dev para staging para produção, ou superfícies não relacionadas, como uma loja virtual e um admin. Leia sets-promotions.md primeiro.
- Consumidores? Uma aplicação pode usar o alvo
allpadrão, que não tem seletores e inclui todas as definições ativas. Várias superfícies geralmente recebem tags comoweb,ioseandroid, e um alvo por superfície. - Formato do arquivo? YAML (padrão) ou JSON.
- O que identifica um usuário?
userId,deviceId, ou ambos (bucketBy: { or: [userId, deviceId] }). O lint exigebucketByem cada funcionalidade, então isso decide o que cada funcionalidade declara e quais atributos vêm primeiro.
Faça o scaffold em um diretório vazio, em seu próprio repositório, separado do código da aplicação:
npx @featurevisor/cli@latest init
npm install
--example=with-environments fornece regras com chave de ambiente, --example=environments fornece Conjuntos como canais de lançamento, e --example=sets fornece superfícies independentes. A tabela de configuração da CLI lista todos os exemplos. Depois, ajuste featurevisor.config.js de acordo com as respostas da entrevista. templates/example-project/ é um projeto v4 completo que passa no lint e no teste, útil como referência de como as peças se encaixam.
Projeto existente? Detecte a versão e a forma antes de tocar em qualquer coisa
Confirme que o projeto tem um @featurevisor/cli instalado em seu manifesto de pacote e lockfile, e com npm ls @featurevisor/cli. Depois, execute a CLI instalada a partir do projeto:
npx featurevisor --version
Ela deve resolver o binário do próprio projeto. Se estiver faltando ou o npx se oferecer para baixar um pacote, pare e pergunte sobre restaurar as dependências travadas do projeto. Não instale uma CLI remota ou atualize dependências apenas para detectar uma versão.
- 4.x: tudo neste skill se aplica.
- 3.x: a sintaxe v3 é diferente. Ela usa
segmentsem regras erequiredFeaturesem vez deconditionsunificadas, e não tem condições de variáveis, composições,continue,checksde teste, cenários e vários operadores. Não escreva sintaxe v4 em um projeto v3. Mantenha-se dentro do que upgrading-to-v4.md lista como sintaxe v3, e ofereça a atualização quando a solicitação precisar de v4. - 2.x: formas como
scopes:, um diretórioenvironments/oucreateInstanceno código da aplicação. Ofereça upgrading-to-v3.md primeiro.
Os consumidores decidem o que você pode publicar. Datafiles v4 precisam de SDKs v4: SDKs v3 não entendem conditions unificadas, então as regras param de corresponder. O schemaVersion do datafile é informativo e não faz um SDK antigo rejeitar o arquivo. Antes de introduzir uma capacidade de tempo de execução, como acúmulo de substituições ou um operador mais recente, confirme a versão do SDK de cada aplicação que consome aquele datafile. Pergunte ao usuário quando isso for desconhecido. Verifique cada uma contra a matriz de compatibilidade de SDKs. Os números de versão nativos diferem, então não presuma que todo SDK compatível é numerado como 4.x. O sucesso do lint da CLI sozinho não estabelece suporte de tempo de execução. Verificações de teste e cenários exigem executores de CLI compatíveis, o que é uma questão separada do que os consumidores suportam.
Depois, leia a configuração:
npx featurevisor config --json --pretty
npx featurevisor info
Quatro valores mudam a forma de tudo que você escreve:
sets: quandotrue, cada definição fica emsets/<set>/e os comandos usam--set. Leia sets-promotions.md primeiro.environments: quando declarado, asrules,forceeexposeda funcionalidade, e osoverridesde variável global, são mapas chaveados por ambiente. Sem isso, são listas diretas, eexposeé um booleano ou lista de tags.parser: escreva JSON para"json", YAML para"yml"(padrão), ou o formato customizado configurado (custom-parsers.md).namespaceCharacter: separador para chaves de subdiretórios. Padrão., entãofeatures/checkout/promo.ymlécheckout.promo. Alguns projetos usam/. Cada referência deve usar o separador do projeto. Confirme com chaves reais usandonpx featurevisor list --segments --json.
Observe também tags (cada tag que você usa deve ser declarada), disallowOperators, allowedConditions e substituições de diretório como featuresDirectoryPath. Depois, leia uma ou duas definições existentes para combinar com o estilo local antes de adicionar novas.
Como o Featurevisor se encaixa
| Definição | Caminho | Propósito |
|---|---|---|
| Atributo | attributes/<chave>.yml | Declara uma chave de contexto e seu tipo. Nunca tem namespace. |
| Segmento | segments/<chave>.yml | Nomeia um público através de conditions. |
| Funcionalidade | features/<chave>.yml | Uma flag, variações opcionais e variáveis de funcionalidade, com regras de rollout. Com bucketing. |
| Variável global | variables/<chave>.yml | Um valor tipado com substituições ordenadas, ou uma compose de outros valores. Nunca tem bucketing. |
| Esquema | schemas/<chave>.yml | Uma forma de variável reutilizável. |
| Alvo | targets/<chave>.yml | Quais definições vão para um datafile. |
| Especificação de teste | tests/**/*.spec.yml | Afirmações de funcionalidades, segmentos e variáveis, e cenários independentes. |
Condições são uma gramática usada em todos os lugares onde uma definição seleciona ou bloqueia: segmentos, regras, entradas de força, bloqueios raiz e substituições. Uma folha compara um atributo, nomeia um segmento com uma string simples, requer uma funcionalidade ou compara o valor de uma variável. Uma lista significa AND, e grupos and, or e not aninham. '*' corresponde a todos, mas apenas como a expressão inteira.
conditions:
- attribute: country
operator: equals
value: nl
- payingAccounts # uma string simples é sempre uma chave de segmento
- feature: liveChat # requer que liveChat esteja ativado
- variable: maintenanceMode
operator: equals
value: false
Ordem de avaliação. A flag de uma funcionalidade verifica um valor fixo (sticky), depois se a funcionalidade está no datafile, depois a primeira entrada de força correspondente, depois as conditions raiz, depois a primeira regra cujas condições correspondem e, finalmente, a porcentagem dessa regra contra o bucket do usuário. Uma falha de porcentagem não passa para a próxima regra. Uma variável global verifica um valor fixo (sticky), depois as conditions raiz, depois as fontes de composição, se houver, depois a primeira substituição correspondente (e as posteriores também quando uma substituição define continue: true), e finalmente seu padrão. Detalhes: features.md e global-variables.md.
Regras principais de criação
As referências adicionam profundidade, mas nunca substituem estas.
1. Bucketing e chaves de regra são contratos
bucketBymantém o resultado de cada usuário estável enquanto as porcentagens mudam. Escolha uma vez e nunca a mude silenciosamente.- Superfícies com usuários logados usam bucketing por
userId, anônimas pordeviceId, mistas por{ or: [userId, deviceId] }. Os nomes dos atributos variam entre projetos: leiaattributes/e pergunte qual usar quando não for óbvio. Nunca invente nomes de atributos. - As chaves de regra devem ser únicas por lista (por ambiente, quando configurado) e não devem mudar depois que os usuários são colocados em buckets. Os arquivos de estado armazenam os intervalos de variação de cada regra por chave, então uma renomeação os realoca. Adicione uma nova regra em vez de renomear.
2. A primeira regra correspondente vence
As regras são executadas de cima para baixo. Coloque regras restritas, como um país a 100%, acima da regra conditions: '*' (pega-tudo). Depois que uma regra corresponde, sua porcentagem decide, e os usuários acima dela não passam para regras posteriores.
3. Referencie apenas o que existe
Confirme se cada atributo, segmento, funcionalidade e variável que você referencia existe, ou crie-o. Verifique também allowedConditions em featurevisor.config.js: pode limitar quais tipos de condição cada local aceita, por exemplo, regras que apenas nomeiam segmentos (conditions.md). O lint rejeita referências desconhecidas. Ele também rejeita, com archived_reference, qualquer referência a uma definição arquivada a partir de uma definição ou especificação que não esteja ela mesma arquivada. Uma definição arquivada é removida dos datafiles, então uma referência a ela pararia silenciosamente de corresponder e, sob not, corresponderia a todos. O lint verifica definições arquivadas apenas quanto à sua forma, então o que elas usavam pode mudar ou desaparecer depois. Uma referência a uma definição obsoleta é um aviso deprecated_reference. Execute npx featurevisor find-usage antes de arquivar, renomear ou excluir qualquer coisa, e prefira arquivar a excluir: o arquivo arquivado reserva a chave.
4. Pesos de variação somam 100
Cada valor é único. control e treatment são apenas convenções. O lint rejeita pesos que não somam 100. Com a CLI 4.0.0, não fazia isso, então verifique a soma você mesmo nesse caso: uma divisão curta é compilada uma vez, depois cada compilação posterior falha com Invalid saved variation allocation. Para experimentos mutuamente exclusivos, veja mutual-exclusion.md.
5. Condições permanecem portáveis entre SDKs
Cada SDK avalia o mesmo datafile, então o lint aplica um subconjunto portátil:
- Datas (
before,after) usam um timestamp ISO 8601 completo com fuso horário, entre aspas:'2026-11-27T00:00:00Z'. Valores apenas com data ou sem fuso horário falham no lint. Ambos os operadores são estritos. - Versões (
semver*) são strings entre aspas, como'5.5'ou'5.5.0', para que o YAML as mantenha como texto. - Expressões regulares (
matches,notMatches) permitem apenas as flagsg,i,mes, e rejeitam toda construção(?, incluindo não capturador(?:…), além de retroreferências e quantificadores possessivos. - Os operadores são verificados em relação aos tipos declarados. Um atributo
type: stringcomformat: date-timeaceita apenas os operadoresbefore,aftere de presença, einaceita uma lista de strings.
Detalhes e mensagens de lint: operators.md.
6. Combine com a forma do projeto
Ambientes, Conjuntos, analisador e separador de namespace mudam como a mesma solicitação é escrita. Os modelos usam a forma padrão sem ambientes. Em um projeto com ambientes, coloque cada lista de rules, force ou overrides globais sob sua chave de ambiente e adicione environment aos testes.
Definição de pronto
Execute este loop após cada alteração. É assim que você prova que uma alteração faz o que o usuário pediu e fornece as evidências para relatar de volta.
- Lint.
npx featurevisor lintdeve passar. Com--json, cada erro temfilePath,path,messageecode, para que você possa corrigir o campo exato. Reexecute após corrigir: alguns erros só aparecem quando os anteriores em ...