name: xpz-msbuild-build description: Skill para validação de build pós-import via MSBuild, com execução sem interface gráfica, parâmetros explícitos, classificação de resultado e gates de segurança contra reorg não autorizada
xpz-msbuild-build
Skill para execução do pipeline de build do GeneXus por MSBuild, em execução sem
interface gráfica. Destina-se a validação pós-import: detectar erros de especificação,
geração e compilação sem abrir a IDE.
Esta skill não executa reorg por padrão, não substitui o fluxo oficial da trilha paralela da KB e não trata sucesso operacional como evidência suficiente de sucesso funcional.
Depende da mesma infraestrutura de xpz-msbuild-import-export: MSBuild.exe,
instalação do GeneXus e Genexus.Tasks.targets.
Decisões de design registradas
Tasks avaliadas e descartadas nesta skill estão documentadas em
998-ideias-descartadas-e-porque.md: Compile (isolado), BuildOne, Run,
RebuildArtifacts, CustomBuild, SpecifyOneOnly, SpecifyOpenAPI,
GenerateChatbot, GenerateOpenAPI, IdeWebBuildAndDeploy, IdeWebCreateDB,
IdeWebImpactDB.
GUIDELINE
Orquestre o pipeline de build do GeneXus via MSBuild com parâmetros explícitos,
classificação rastreável de resultado e bloqueio de reorg por padrão. Use
Invoke-GeneXusKbSpecifyGenerate.ps1 para verificação pós-import — menos invasiva que
BuildAll quando não há alterações estruturais pendentes no banco, mas capaz de
disparar reorg real quando o modelo as contém. Use Invoke-GeneXusKbBuildAll.ps1
para BuildAll incremental (equivalente à opção Build All do menu Build da IDE
GeneXus — compila apenas objetos alterados desde o último build, fluxo costumeiro
pós-edição/pós-import). -ForceRebuild=true é uma operação distinta: equivale a
Rebuild All da IDE — regenera TODOS os objetos da KB, podendo durar horas em KB
grande; só pode ser habilitado via -AllowWideRebuild com confirmação explícita do
usuário por frase exata. Nunca execute reorg sem autorização explícita do usuário.
Quando houver evidência de alteração estrutural de atributo no import recente, exigir
confirmação explícita do usuário antes de chamar Invoke-GeneXusKbSpecifyGenerate.ps1.
BuildAll ou SpecifyGenerate sem monitoramento legível não é fluxo válido. Há dois
fluxos de monitoramento legítimos:
- (padrão) janela visível — use
-StartWatcherao chamarInvoke-GeneXusKbBuildAll.ps1ouInvoke-GeneXusKbSpecifyGenerate.ps1; o wrapper garante o lançamento automático deWatch-GeneXusMsBuildLog.ps1em janela visível e registra evidência auditável no JSON (watcherContext.watcherLaunched). - (opt-in, build longo) modo desacoplado — lance via
Start-GeneXusKbBuildDetached.ps1, que roda o build sob uma Tarefa Agendada one-shot fora da sessão do agente (sobrevive a fechar a janela ou o app) e sinaliza a conclusão por arquivo-sentinela; o monitoramento legível passa a ser omsbuild.stdout.log(progresso) + a sentinela (conclusão), sem janela.
O modo desacoplado não é o default: o agente o propõe quando o build for esperado
longo ou for rodar em segundo plano, explicando o trade-off (perde a janela de progresso ao
vivo, ganha robustez a fechamento acidental), e só o usa por decisão consciente do usuário.
A ausência de qualquer monitoramento (nem janela, nem sentinela) permanece inválida; a
única exceção é justificativa operacional explícita e documentada (ex.: ambiente sem pwsh
no PATH, CI headless sem terminal) — nesse caso declarar explicitamente ao usuário e registrar
watcherContext.watcherLaunched: false como evidência de ausência. Seguir a seção
ORQUESTRAÇÃO — PASSO A PASSO EXECUTÁVEL.
PATH RESOLUTION
- Este
SKILL.mdfica em uma subpasta de skill sob a raiz do repositório. - Resolva referências
../arquivo.mdrelativas à pasta desta skill, não ao diretório corrente. - Se a skill estiver publicada por symlink, junction ou outro reparse point, resolva primeiro a pasta real da skill e só então interprete referências relativas.
- Na prática,
../aponta para a base metodológica compartilhada da raiz.
TRIGGERS
Use esta skill para:
- executar verificação leve pós-import (specify + generate, sem compile)
- executar build completo pós-import (specify + generate + compile)
- detectar se há reorg pendente após import, sem executá-la
- inspecionar o que a reorg alteraria no banco sem executar (
ImpactDatabaseOnly) - executar reorg a partir de script de impacto já inspecionado (
ReorganizeOnly) - configurar o modo de build antes de
BuildAllviaSetConfiguration(valores:Release,Debug,Performance Test) - classificar resultado de build em categorias operacionais explícitas
- apoiar decisão do usuário sobre o próximo passo após import
- resolver sub-estado
importação real efetiva provada, geração de runtime pendentedeclarado porxpz-msbuild-import-export— quando import está provado mas artefatos de runtime ainda refletem versão anterior, executar build é o passo que atualiza os artefatos gerados no environment usado no build;specify e generate concluídosoucompilou limpoconfirmam sucesso operacional nesse environment — em KB multi-environment não equivalem sozinhos a “a aplicação em IIS/self-host refletiu o import” sem-EnvironmentName/deployment_environment_namealinhados ao deploy; após build de validação deploy, passar-PostImportDeployValidationpara gate de publicação emweb\bin(max de DLL de objeto excluindo runtime GeneXus/System/Microsoft, ou*.config— exit 49 se stale); em Core,GxNetCoreStartup.dllvelho em incremental gera warning, não gate;Test-GeneXusRuntimeFreshness.ps1verificaCSharpModel\web(compartilhado) — complementar, não substituto;Test-GeneXusDeployBinFreshness.ps1diagnostica sóweb\bindo environment de deploy (aceita-BuildResultJsonPathpara tomar a linha de corte detiming.msbuildStartdo build, dispensando-BuildStartedAtmanual)
Do NOT use esta skill para:
- executar reorg sem autorização explícita do usuário
- substituir o fluxo oficial da trilha paralela da KB
- cenários que dependam de
GeneXus Servercomo requisito operacional - KB de produção ou homologação compartilhada sem janela clara para experimento
- inferir silenciosamente
KbPath, versão,Environmentou parâmetros sensíveis - afirmar sucesso funcional apenas porque o build terminou sem erro operacional
RESPONSIBILITIES
- Usar 10-base-operacional-msbuild-headless
como base de infraestrutura compartilhada com
xpz-msbuild-import-export - Antes de chamar
Invoke-GeneXusKbSpecifyGenerate.ps1, avaliar o contexto do import recente em busca de sinais de alteração estrutural com impacto em banco:- qualquer objeto do tipo
Attribute:presente emimportedItemsdo log de import - mudança de tamanho, tipo, precisão ou subtipo de atributo mencionada pelo usuário
- resultado
reorg detectada ou executadaem execução anterior desta sessão Se qualquer sinal estiver presente, exibir aviso explícito e exigir a frase de confirmaçãoentendo que haverá reorg e concordo que prossigaantes de executar
- qualquer objeto do tipo
- Tratar
C:\Program Files (x86)como estritamente somente leitura - Garantir que logs, temporários,
.msbuilde artefatos sejam gerados fora deC:\Program Files (x86) - Usar
FailIfReorg=truecomo default deBuildAll— nunca alterar sem instrução explícita - Nunca emitir
DoNotExecuteReorg=falseimplicitamente: reorg só executa quando o usuário pedir explicitamente com plena ciência do efeito - Tratar
-ForceRebuild=truecomo operação ampla análoga a reorg autorizada: bloqueada por default e habilitada apenas via-AllowWideRebuildcom confirmação explícita do usuário por frase exata (modo interativo) ou-AllowWideRebuild -ConfirmWideRebuildapós confirmar com o usuário humano (modo não-interativo). Nunca emitirForceRebuild=trueimplicitamente em fluxo pós-import nem em validação cotidiana —BuildAllincremental é o suficiente - Tratar
-CompileMains=truee-DetailedNavigation=truecomo opções caras de build: bloqueadas por default e habilitadas apenas via-AllowCostlyBuildOptionscom confirmação explícita do usuário por frase exata (modo interativo) ou-AllowCostlyBuildOptions -ConfirmCostlyBuildOptionsapós confirmar com o usuário humano (modo não-interativo). Nunca emitir essas opções implicitamente em fluxo pós-import nem em validação cotidiana - Distinguir claramente:
- sucesso operacional da chamada MSBuild
- efeito funcional observado depois no GeneXus
- Distinguir Categoria B (linhas
error :no log MSBuild capturadas embuildErrors/specifyErrorsno top-level do JSON): quandoexecutionEvidence.msBuildExitCode=0mas essas listas não estiverem vazias, o wrapper rebaixa paraexitCode=48(msBuildCategoryBBlocked=true) estatusfalha operacional com rejeicao MSBuild no log— não classificar comocompilou limponemspecify e generate concluídos; detalhe em 10-base-operacional-msbuild-headless.md e secção «Categorias A e B» em xpz-msbuild-import-export/SKILL.md; catálogo numérico emscripts/msbuild-exit-codes.catalog.json - Classificar o resultado de cada execução em uma das categorias definidas em WORKFLOW
- Registrar
stdout,stderr,exitCode, caminho do.msbuildtemporário e log - Recomendar reabertura da KB na IDE somente quando houver warning ou efeito colateral
detectado no build (ex: extensão ausente,
Access denied, stderr não vazio), ou quando o contexto da solicitação indicar que o objetivo é validar a aplicação em execução — não mencionar IDE nem URL em builds sem warning onde apenas "faça um build" foi pedido; quando a condição estiver presente (ex: stderr não vazio), formular a recomendação como consequência determinística da evidência encontrada — citar o padrão específico detectado e recomendar explicitamente (ex: "stderr não estava vazio: [padrão]; recomendo reabrir a KB na IDE para conferência funcional antes de tratar o build como validado"); não enquadrar como sugestão condicional ao interesse do usuário - Exigir confirmação explícita antes de qualquer execução de reorg
- Tratar
ImpactDatabaseOnlycomo pré-requisito de inspeção antes de autorizarReorganizeOnlyexplícito - Exigir confirmação interativa obrigatória antes de
ReorganizeOnly, mesmo quandoImpactDatabaseOnlyjá foi executado na mesma sessão - Tratar
SetConfigurationcomo operação auxiliar opcional de pré-build: só emitir quando explicitamente solicitado pelo usuário, com valor validado (Release,Debug,Performance Test) - Nunca inferir ou alterar configuração sem instrução explícita
- Validar explicitamente
KbPath,GeneXusDir,MsBuildPath,WorkingDirectory,LogPatheGenexus.Tasks.targetsantes de qualquer build - Quando
SetActiveVersionouSetActiveEnvironmentfalhar, tratar como bloqueio operacional explícito: a versão ou oEnvironmentsolicitado não existe na KB. O diagnóstico deve orientar omitir-VersionNameou-EnvironmentNamepara usar o contexto ativo somente quandokb_environment_countemkb-source-metadata.mdfor1(ou quando o objetivo for explicitamente o environment ativo da IDE). Em KB multi-environment (kb_environment_count> 1), nunca omitir-EnvironmentNamena validação pós-import alinhada ao deploy — usar parâmetro explícito oudeployment_environment_namegravado peloxpz-kb-parallel-setup. - Validação deploy (objetivo A) vs fix completo multi-environment (objetivo B):
- A: um build (
BuildAllouSpecifyGenerate) com-EnvironmentNameigual ao environment que serve a aplicação (campodeployment_environment_nameno metadata, ou parâmetro). ConferirobservedContext.ActiveEnvironmentno JSON — deve coincidir com o environment de validação resolvido (deploymentEnvironmentContextno JSON). - B: quando a frente exigir fechamento em mais de um generator ativo — opt-in, não
gate pós-import automático. Prática usual: após A no environment de deploy, Build na IDE
nos demais environments que a frente ainda cobre (consultar
kb_environment_namesno metadata); falha no segundo environment após A bem-sucedido é rara. Headless repetido com-EnvironmentNamepor env é opcional, não padrão. Ver 02-regras-operacionais-e-runtime.md (seção «Saída do gerador GeneXus por environment»). Não confundir A bem-sucedido com B completo.
- A: um build (
- Ao chamar
Invoke-GeneXusKbBuildAll.ps1ouInvoke-GeneXusKbSpecifyGenerate.ps1a partir de pasta paralela, passar-ParallelKbRoot(ou-KbMetadataPath). Os wrappers leemkb_environment_count,deployment_environment_name,kb_environment_names,deployment_hosting_kinde, quando a validação de deploy bin estiver ativa,kb_environment_web_dirsdo metadata — não inventariam environments nem inferem caminho deweb\binpor pastas da KB nativa em cada build. - Para diagnostico de
.csgerado, resolver o caminho comResolve-GeneXusGeneratedCsPath.ps1, que lekb_environment_web_dirsno mesmo metadata; metadata sem esse campo volta paraxpz-kb-parallel-setup. - Quando o build falhar com erros C# compatíveis com arquivo gerado truncado, como
CS1010(newline em constante) eCS1513(}esperada) repetidos no mesmo.cs, verificar primeiro se o artefato gerado termina abruptamente, sem string/funcao fechada ou sem newline final. Se esses sinais aparecerem, classificar como suspeita de falha de geração truncada e tentar regeneração controlada antes de investigar o XML;-ForceRebuild=truecontinua proibido sem o gate de regeneração ampla (-AllowWideRebuild+ frase exata). Ver 02-regras-operacionais-e-runtime.md, seçãoDiagnostico de codigo gerado truncado por falha de generation. - Quando o contexto vier de
xpz-msbuild-import-exportcom import OK (importação real efetiva provadaou equivalente) mas o evento GeneXus não surtir efeito na UI, ou quando o usuário pedir inspeção pós-build do.cspor suspeita de mecanismo (b) (strip silencioso por DCE), tratar como frente de conteúdo gerado, não como falha do wrapper de build nem como reabertura do sub-estado de import. Após build ouSpecifyGenerateconcluído com artefato gerado disponível, buscar no.csreferenciado pelo nome do evento; zero ocorrências ou handler com corpo vazio/sem efeito observável reforça hipótese (b). Ver 02-regras-operacionais-e-runtime.md, seçãoMecanismos de descarte de codigo de evento pelo gerador GeneXus; para verificação estrutural deoparmseajax_rsp_assign_sdt_attriemWebPanel, ver também subseçãoWebPanel, Tab aninhada e re-bind de SDT em data attributesno mesmo02. - Para Transaction e sintomas do tipo “rule não dispara” ou “valor não chega no browser” após import OK com geração pendente ou concluída, complementar a busca por evento com
scripts/Find-CsAttributeAssignments.ps1no.csweb da transação (-CsPathabsoluto,-Attributecom ou sem prefixoA<n>,-AsJson): mapeia cópias da atribuição por método (OnLoadActions*,CheckExtendedTable*,Valid_*, etc.), indicaAssignAttrino mesmo método e detecta triplet típico (override INS/Insert_*, default por proc, fallback ternário) comcascadeOrderpara diagnóstico deif/else ifmutuamente exclusivos. Para a entrada nomeada, vertransaction-attribute-rule-shadowed-by-default-in-cascadeem 02-regras-operacionais-e-runtime.md. - Mecanismo (a) — rejeição na importação: se o sintoma for
Unknown function '<nome>',src0294(ou similar) ouexitCode != 0/errorsnoimport.jsonde importação, não investigar o.csgerado como causa primária nesta skill; classificar como frente de import/source e handoff paraxpz-msbuild-import-exportou correção no XPZ antes de novo build. - Mecanismo (b) — strip por DCE: sucesso operacional de build não prova que o evento foi preservado no
.cs; a correção típica é tornar o corpo do evento observável ao gerador (ex.: operação opaca via proc externa), conforme02— não ajustar parâmetros do wrapper de build nem presumir envelope/XML inválido.
COMMUNICATION
- Responda no idioma do usuário
- Declare sempre a categoria de resultado (ver WORKFLOW) de forma explícita
- Quando o resultado for
reorg necessária detectada, apresente isso como informação, não como falha — e pergunte como o usuário quer proceder - Quando houver timeout em KB grande, não interprete automaticamente como falha
- Não use linguagem otimista para sugerir segurança que ainda não foi validada
- Quando houver ambiguidade de contexto, interrompa e peça definição explícita
- Quando receber handoff de
xpz-msbuild-import-exportcom import OK e suspeita de mecanismo (b), declarar explicitamente que o sub-estado de import não é reaberto pelo resultado do build; reportar separadamente categoria de resultado do build (WORKFLOW) e achado da inspeção do.cs(handler ausente, strip por DCE, ou handler presente comoparms/SDT conforme02) - Quando a inspeção do
.csconfirmar strip por DCE, orientar correção no source/XPZ conforme 02-regras-operacionais-e-runtime.md, seçãoMecanismos de descarte de codigo de evento pelo gerador GeneXus, e não tratarcompilou limpoouspecify e generate concluídoscomo prova de que o evento GeneXus foi preservado
STRUCTURE
Arquivos de referência e quando carregar:
| Referência | Carregar quando |
|---|---|
| README.md | Sempre — regras editoriais e posicionamento da base |
| 10-base-operacional-msbuild-headless.md | Sempre — base de infraestrutura MSBuild compartilhada |
| 02-regras-operacionais-e-runtime.md | Regras operacionais e restrições da trilha XPZ; carregar também após handoff de import OK com evento ausente no .cs/UI (mecanismo b), para inspeção pós-build do handler e procedimento em Mecanismos de descarte de codigo de evento pelo gerador GeneXus; e quando erros C# sugerirem .cs truncado (CS1010/CS1513) |
| xpz-msbuild-import-export/SKILL.md | Handoff quando o sintoma for mecanismo (a) (Unknown function/src0294, exitCode != 0 ou errors no import.json) ou quando faltar sub-estado/classificação de import antes de inspecionar .cs |
Skills externas não listadas nesta tabela não devem ser carregadas durante a execução desta skill sem necessidade concreta derivada do contexto específico da tarefa; xpz-msbuild-import-export na tabela acima é exceção documentada para handoff de importação e classificação (a)/(b).
EXPECTED INTERFACE
Dois scripts PowerShell próprios, seguindo o mesmo padrão de xpz-msbuild-import-export, um wrapper integrador de handoff pós-import e um orquestrador opt-in de lançamento desacoplado.
Invoke-GeneXusXpzImportThenBuild.ps1pertence operacionalmente à trilhaxpz-msbuild-import-export, mas chamaInvoke-GeneXusKbBuildAll.ps1como etapa receptora. O build só roda quandoimportReadyForBuild.ready=true; combuildSkippedReason, tratar como import não apto para build, não como falha autônoma de build.Start-GeneXusKbBuildDetached.ps1é o orquestrador opt-in do modo desacoplado (build longo / em segundo plano): registra uma Tarefa Agendada one-shot que executaInvoke-GeneXusKbBuildAll.ps1fora da sessão do agente e sinaliza a conclusão por arquivo-sentinela. Não altera o wrapper de build (apenas o invoca) e é transporte, não autoridade de política — os gates de reorg/rebuild/opções caras permanecem no wrapper. Contrato e fluxo na subseção Modo desacoplado (opt-in, build longo) da ORQUESTRAÇÃO. Self-test:scripts/Test-StartGeneXusKbBuildDetachedContract.ps1.Wait-GeneXusKbBuildDetached.ps1é o helper de espera do modo desacoplado: combina sentinela + heartbeat da Tarefa Agendada (com margem de corrida e timeout) para não ficar preso quando o processo morre de forma dura sem escrever a sentinela. Somente leitura; retornaoutcome(concluido/falha-anomala/timeout); exit 0/70/71. Self-test:scripts/Test-WaitGeneXusKbBuildDetachedContract.ps1.
Categoria B (rejeição MSBuild no log)
Barragem estrutural compartilhada: scripts/GeneXusMsBuildCategoryBSupport.ps1 (exit 48 em scripts/msbuild-exit-codes.catalog.json). Antes de varrer stdout/stderr manualmente ou declarar sucesso com executionEvidence.msBuildExitCode=0, ler no top-level do JSON de resultado: exitCode, msBuildCategoryBBlocked, operationalSubState, buildErrors (em BuildAll) ou specifyErrors (em SpecifyGenerate) e blockingReasons. Com exitCode=48, reproduzir as linhas error : ao usuário e tratar o resultado como não confiável para handoff operacional — mesmo que a task MSBuild tenha concluído com sucesso aparente.
TransactionEvents+spc0150: sebuildErrors/specifyErrorsou o log trouxerspc0150: Cannot update database. Changes to database are only allowed in procedures.emTransactionEvents, ver anti-padrãotransaction-event-attribute-assignment-rejectedem 02-regras-operacionais-e-runtime.md e Catálogo 2 em xpz-builder/responsibilities-by-type/transaction.md. Não atribuir atributos daTransactiondentro deEvent; valores persistidos ficam em rules declarativas (escopo motor XPZ; modelagem GeneXus: nexa).
Pós-processamento resiliente (BuildAll / SpecifyGenerate)
Após a task MSBuild concluir, Invoke-GeneXusKbBuildAll.ps1 e Invoke-GeneXusKbSpecifyGenerate.ps1 envolvem parse de stdout, montagem do diagnóstico e serialização JSON em try/catch (motor compartilhado scripts/GeneXusMsBuildGamPlatformsSupport.ps1 para filtro GAM/NetCore).
postProcessingFailed/postProcessingError— falha local do wrapper depois que oMSBuildjá rodou (parse, classificação, hints consultivos, serialização ou gravação do log). Não reclassificam automaticamenteexecutionEvidence.msBuildExitCode=0como falha operacional nem elevam para exit 90 quando a evidência primária do log bruto sustenta conclusão limpa da task.- Evidência primária por trilha quando
postProcessingFailed=trueeexecutionEvidence.msBuildExitCode=0:- build-all:
__BUILDALL_DONE__=truenomsbuild.stdout.loge/ouobservedContext.BuildAllDone=trueno JSON parcial; status pode permanecercompilou limpocomexitCode=0esummaryindicando falha só no pós-processamento. - specify-generate:
__SPECIFY_DONE__=truee/ou__GENERATE_DONE__=trueno log bruto e/ouobservedContext.SpecifyDone/observedContext.GenerateDoneno JSON parcial; status pode permanecerspecify e generate concluídoscomexitCode=0.
- build-all:
buildSignals(presente nos objetos enxutos$fallbackde serialização e$recoveryexterno do build-all quando o JSON saiu parcial) carrega adiante sinais já computados no caminho normal para o agente não precisar reabrir o log bruto:ReorgDetected,ErrorCountePostBuildEvents(as linhas da janela pós-build, o.batde deploy inclusive, pelo nome real — sem detector dedicado).Complete=true⇒ esses sinais são integrais e confiáveis (não reabrir o log para eles);Complete=false⇒ bucket parcial, e camponullnão é0/[](significa "não chegou a ser computado") — reabrir o log só para os camposnull. ConsultarbuildSignalsantes do log bruto.- Consultar
artifacts.MsBuildStdoutLogPath/executionEvidence.StdOutPathquando o JSON estiver parcial, comnoteapontando log bruto. environmentRemediationHintsé omitido quando não houve ruído GAM filtrado; falha ao montar hints com stdout limpo não deve derrubar o pós-processamento inteiro (Get-GamPlatformsStdoutPostFilterResult).
Contrato transversal ampliado (import/export/preview): 10-base-operacional-msbuild-headless.md e xpz-msbuild-import-export/SKILL.md.
Find-CsAttributeAssignments.ps1
Motor compartilhado de diagnóstico no .cs gerado (camada web), complementar aos wrappers MSBuild — não substitui classificação de import nem prova sucesso de build.
Quando usar: import OK (importação real efetiva provada ou equivalente) com geração pendente ou concluída, e sintomas em Transaction do tipo “rule não dispara” ou “valor não chega no browser”; também após SpecifyGenerate/BuildAll quando o .cs da transação estiver disponível. Para WebPanel e mecanismo (b) (evento/handler/DCE), priorizar busca pelo nome do evento conforme 02; este script não mapeia handlers de evento.
Parâmetros:
-CsPath(obrigatório) — caminho absoluto do.cs(ex.:<KbPath>\<Environment>\web\<transaction>.cs)-Attribute(obrigatório) — nome com ou sem prefixoA<n>; o motor normaliza para a forma canônica no arquivo-AsJson(opcional) — saída estruturada (methods[],totals,tripletPattern.cascadeOrder,hasAssignAttriInMethod)
Antes de montar -CsPath, preferir scripts/Resolve-GeneXusGeneratedCsPath.ps1 com -KbPath, -ParallelKbRoot/-KbMetadataPath, -EnvironmentName quando necessário e -ObjectName. O resolvedor usa kb_environment_web_dirs em kb-source-metadata.md; se o campo estiver ausente, bloquear e encaminhar para xpz-kb-parallel-setup, sem glob recursivo na KB nativa nem inferencia por CSharpModel.
Mapa dos métodos .cs gerados onde a atribuição pode aparecer: use methods[].name como nome literal gerado e cruze com o mapa canônico longo em xpz-builder/responsibilities-by-type/transaction.md.
| Padrão de nome do método | Cenário de runtime | Gatilho JS / AJAX | AssignAttri típico |
Quando aparece |
|---|---|---|---|---|
OnLoadActions<KbId> |
carga inicial, refresh leve de FK e recarga parcial server-side | refresh AJAX genérico; também dentro de outros fluxos | presente | observado como método único por Transaction com cópia da rule |
CheckExtendedTable<KbId> |
validação pesada no Confirm/Save | submit do form, Confirmar / btn_enter |
presente | observado como método único por Transaction com cópia da rule |
Valid_<FKDoLado> |
validação de FK quando o JS decide chamar VALID_<FK> |
evento AJAX VALID_<FK> em setEventMetadata |
pode faltar | depende de FK usada pela expressão ou condição da rule; variações negativas ficam padrao-gx-nao-verificado sem corpus adicional |
GX<n>ASA<ATTR><KbId> |
handler AJAX do prompt-aggregator-selector do atributo | gxfirstwebparm como gxajaxAggSel<n>_<ATTR> |
presente | depende de prompt-control associado ao atributo; sem prompt fica padrao-gx-nao-verificado sem corpus adicional |
A rule pode estar presente nesses métodos e ainda assim ficar "escondida" em runtime se a cascata interna if/else if sombrear a atribuição; ver o anti-padrão transaction-attribute-rule-shadowed-by-default-in-cascade em 02-regras-operacionais-e-runtime.md.
Interpretação de cascadeOrder: os valores conhecidos override-then-default-then-fallback e override-then-fallback-then-default descrevem a ordem efetiva de ramos if/else if mutuamente exclusivos no .cs gerado. Trate isso como diagnóstico em quarentena XPZ, não como catálogo geral de modelagem GeneXus. Quando a correção aprovada for inverter a ordem textual de Rules no XML da frente, aplicar com scripts/Edit-GeneXusXmlSurgical.ps1 (-DryRun, âncora literal, contagem esperada de âncoras e baseline de lastUpdate quando houver) e repetir import/build + leitura do .cs antes de encerrar. Entrada canônica: transaction-attribute-rule-shadowed-by-default-in-cascade em 02-regras-operacionais-e-runtime.md.
Regressão: scripts/Test-FindCsAttributeAssignmentsContract.ps1 (sentinela FIND_CS_ATTRIBUTE_ASSIGNMENTS_CONTRACT_OK).
Invoke-GeneXusKbSpecifyGenerate.ps1
Executa SpecifyAll seguido de GenerateOnly. Sem compilação explícita. Mais rápido
que BuildAll para o primeiro check após import cirúrgico — mas pode disparar
reorganização real de banco de dados quando a KB tem alterações estruturais pendentes,
pois SpecifyAll executa reorg internamente nesse caso. Ver gate pré-execução em
WORKFLOW e nota de comportamento crítico abaixo.
Parâmetros transversais:
-KbPath(obrigatório)-GeneXusDir(opcional — fallback automático)-MsBuildPath(opcional — fallback automático)-VersionName(opcional)-EnvironmentName(opcional)-WorkingDirectory(obrigatório)-LogPath(obrigatório — caminho de arquivo de log onde o wrapper grava o JSON de resultado; apontar para um diretório existente é bloqueado cedo com exit 50 — gate fail-fastparametro-invalido, antes de abrir a KB / registrar tarefa; motorscripts/GeneXusMsBuildLogPathSupport.ps1)-VerboseLog(opcional)-MonitorLogPath(String, opcional — caminho do arquivo gravado pelo parâmetro-MonitorLogdeWatch-GeneXusMsBuildLog.ps1; quando fornecido e o arquivo existir após a execução, o wrapper extrai os timestamps das fases internas (iniciado/terminado) e populatiming.phasesno JSON de resultado; sem este parâmetro,timing.phasesfica vazio mas os tempos totais da execução continuam sendo gravados; obrigatório quando-StartWatcherfor passado — bloqueado por política com exit 46 se ausente)-StartWatcher(switch — quando presente, o próprio wrapper disparaWatch-GeneXusMsBuildLog.ps1em janela visível comStart-Process pwshantes de iniciar o MSBuild; requer-MonitorLogPath; o watcher recebe o PID do processo wrapper como alvo de monitoramento; o resultado JSON incluiwatcherContextcomwatcherLaunched,watcherPid,watcherScriptPath,watcherMonitorLogPathewatcherLaunchError; se o watcher falhar ao iniciar, a execução prossegue com warning — não bloqueia a execução)-WatcherIntervalSeconds(Int, default5— intervalo de polling em segundos repassado ao watcher; usado apenas quando-StartWatcherestá presente; intervalo válido: 1-60)-WatcherSilenceThresholdSeconds(Int, default120— segundos sem nova linha no log antes de o watcher emitir alerta de silêncio; repassado ao watcher; usado apenas quando-StartWatcherestá presente; intervalo válido: 30-3600)
O contrato de watcher acima vale para Invoke-GeneXusKbSpecifyGenerate.ps1 e
Invoke-GeneXusKbBuildAll.ps1. Ele é centralizado em
scripts/GeneXusMsBuildWatcherSupport.ps1; ao evoluir watcher, timing ou
watcherContext, manter o helper comum como sede da regra e evitar lógica divergente
dentro dos wrappers.
Limitação conhecida de
timing.phases: somente fases com par completo (iniciado+terminado) aparecem na lista. Fases cujoterminadonunca é emitido — por erro ou abort — são silenciosamente omitidas (ex.:Atualização de configuração da webquando o GeneXus falha antes de concluí-la). Pares com grafia inconsistente entreiniciadoeterminado(ex.:Get Active VersionvsGetActiveVersion) são normalizados e fechados corretamente; o camponameno JSON usa a grafia doterminado.
Se -VersionName ou -EnvironmentName for informado com valor inválido para a KB, o
wrapper deve detectar a falha de SetActiveVersion/SetActiveEnvironment, emitir
blockingReasons específico e orientar omitir o parâmetro para usar o contexto ativo.
Parâmetros específicos:
-ForceRebuild(Boolean, defaultfalse— quandotrue, equivale aRebuild Allda IDE: mudaSpecifyAll/GenerateOnlyde incremental para regeneração total de TODOS os objetos da KB; em KB grande pode levar horas; só pode ser habilitado via-AllowWideRebuild— tentativa sem essa autorização é bloqueada por política com exit 46)-DetailedNavigation(Boolean, defaultfalse; opção cara, só pode ser habilitada via-AllowCostlyBuildOptions)-AllowWideRebuild(switch — único caminho autorizado para habilitar-ForceRebuild true; em modo interativo exige que o usuário digite a frase exataentendo que isto pode regerar a KB inteira e aceito o custo; em modo não-interativo requer-ConfirmWideRebuild; comForceRebuild=false, o switch é redundante: o wrapper registra warning emwarnings, não pede a frase exata e mantémAllowWideRebuildConfirmed=false)-ConfirmWideRebuild(switch — usado em conjunto com-AllowWideRebuildpara dispensar oRead-Hostinterativo da frase de confirmação; destina-se a processos desanexados onde não há terminal disponível; proibido sem-AllowWideRebuild; o chamador é responsável por confirmar com o usuário humano antes de passar este parâmetro)-AllowCostlyBuildOptions(switch — único caminho autorizado para habilitar-DetailedNavigation true; em modo interativo exige que o usuário digite a frase exataentendo que estas opcoes podem ampliar muito o custo do build e aceito executar; em modo não-interativo requer-ConfirmCostlyBuildOptions)-ConfirmCostlyBuildOptions(switch — usado em conjunto com-AllowCostlyBuildOptions; proibido sem-AllowCostlyBuildOptions; o chamador é responsável por confirmar com o usuário humano antes de passar este parâmetro)
Categorias de resultado:
falha operacional com rejeicao MSBuild no log— Categoria B:executionEvidence.msBuildExitCode=0masspecifyErrorspopulado;exitCode=48,msBuildCategoryBBlocked=true,operationalSubStatetipicamentebuild com errors do MSBuild — resultado não confiável; reproduzir linhaserror :ao usuário; não declararspecify e generate concluídosspecify e generate concluídos— ambas as etapas passaram com exitCode 0 (classificado pelo wrapper, sem Categoria B), stdout sem padrões de alerta após filtro de ruído estrutural conhecido em stdout (ver padrões abaixo) e sem conteúdo real em stderr após filtro de ruído estrutural conhecidoreorg detectada ou executada— padrãoReorganizaencontrado em stdout;SpecifyAlldisparou reorganização real de banco de dados; não declarar sucesso; apresentar ao usuário e aguardar instrução explícitaoperação concluída, pendente de confirmação funcional— exitCode 0, mas impedimentos detectados: stderr não vazio, padrões de alerta (Access denied) ou eventos pós-build não registrados/não reconhecidos em stdout (eventos registrados emkb_environment_post_build_event_hashesnão rebaixam)erro de specify—SpecifyAllfalhou; objetos com referências inválidas ou inconsistênciaerro de generate—GenerateOnlyfalhou após specify bem-sucedidoKB inacessível—OpenKnowledgeBasefalhou antes de qualquer etapa de build
Comportamento crítico conhecido — SpecifyAll não é leve quando há alterações estruturais pendentes: A task
SpecifyAlldo GeneXus executa internamente: Database Impact Analysis, geração deReorganizationScript.txtebldReorganization.cs, reorganização real do banco (gxexec bldReorganization.cs), especificação, segunda geração e eventos pós-build configurados na KB (ex.:start cmd, deploy automático). Esse comportamento é intrínseco à task quando o modelo tem alterações estruturais pendentes e independe de qualquer parâmetro do wrapper.SpecifyAllnão expõeFailIfReorgnem equivalente — ao contrário deBuildAll. A classificaçãoreorg detectada ou executadasinaliza este cenário como bloqueante.
Padrão conhecido — ruído estrutural do
dotnet publishemGAM\Platforms\NetCore*(stdout): Mesmo padrão e mesma lógica de filtro documentados em detalhe na seçãoInvoke-GeneXusKbBuildAll.ps1(assinaturas:MSB3491ouNuGet.targets(...): error :, sempre com mensagem de acesso negado e caminho contendo\GeneXus\...\Library\GAM\Platforms\).Invoke-GeneXusKbSpecifyGenerate.ps1aplica o mesmo filtro e populastdoutFilteredNoiseno diagnóstico. Quando houver ruído GAM filtrado, o JSON pode incluirenvironmentRemediationHints(mesmo contrato documentado na seçãoInvoke-GeneXusKbBuildAll.ps1).Cobertura empírica: a evidência da matriz 2×2 foi coletada via
BuildAll. Não foi verificado empiricamente seSpecifyAllpuro (sem compile) também dispara a fase deInicialização Integrada de Segurançaque origina o ruído. O filtro é seguro de qualquer forma: se o ruído não aparecer no fluxoSpecifyGenerate, o filtro é idempotente (não remove nada que não esteja lá); se aparecer, é removido com a mesma assinatura precisa. Quando houver primeira execução real que confirme presença ou ausência do ruído neste fluxo, atualizar a evidência empírica acima.
Padrão conhecido — ruído estrutural do GeneXus 18 em stderr: O GeneXus 18 escreve exatamente 3 linhas
context [anonymous] 1:12 attribute component isn't definedno stderr durante oSpecifyAll.Invoke-GeneXusKbSpecifyGenerate.ps1filtra esse padrão antes de classificar o status — uma execução bem-sucedida cujo stderr contenha apenas esse ruído é classificada comospecify e generate concluídos. Ver nota expandida com evidência técnica completa na seçãoInvoke-GeneXusKbBuildAll.ps1.
Invoke-GeneXusKbBuildAll.ps1
Equivalente à opção Build All do menu Build da IDE GeneXus: executa BuildAll, que
faz specify + generate + compile dos objetos alterados desde o último build (build
incremental). Detecta — mas não executa por padrão — reorg necessária. Esta é a etapa
cotidiana após import/edição. Para Rebuild All (regeneração total de TODOS os
objetos), ver -ForceRebuild abaixo, que só pode ser usado com -AllowWideRebuild
e confirmação explícita por frase exata.
Parâmetros transversais: mesmos do Invoke-GeneXusKbSpecifyGenerate.ps1.
Parâmetros específicos:
-ForceRebuild(Boolean, defaultfalse— quandotrue, equivale aRebuild Allda IDE: muda a semântica deBuildAllincremental para regeneração total de TODOS os objetos da KB, independentemente de mudança; em KB grande pode levar horas e regenerar centenas/milhares de objetos, incluindo subtype groups; só pode ser habilitado via-AllowWideRebuild— tentativa sem essa autorização é bloqueada por política com exit 46)-CompileMains(Boolean, defaultfalse— compila apenas Developer Menu; opção cara, só pode ser habilitada via-AllowCostlyBuildOptions)-DetailedNavigation(Boolean, defaultfalse; opção cara, só pode ser habilitada via-AllowCostlyBuildOptions)-FailIfReorg(Boolean, defaulttrue— bloqueia build se houver reorg pendente)-DoNotExecuteReorg(Boolean, defaultfalse)-AllowReorg(switch — quando presente, defineFailIfReorg=falseeDoNotExecuteReorg=false; em modo interativo exige que o usuário digitesimno terminal; em modo não-interativo requer-ConfirmReorg)-ConfirmReorg(switch — usado em conjunto com-AllowReorgpara dispensar oRead-Hostinterativo; destina-se a processos desanexados onde não há terminal disponível, como quandoWatch-GeneXusMsBuildLog.ps1roda em paralelo; proibido sem-AllowReorg; o chamador é responsável por confirmar com o usuário humano antes de passar este parâmetro)-AllowWideRebuild(switch — único caminho autorizado para habilitar-ForceRebuild true; em modo interativo exige que o usuário digite no terminal a frase exataentendo que isto pode regerar a KB inteira e aceito o custo; em modo não-interativo requer-ConfirmWideRebuild; gate independente do gate de reorg —-AllowReorgnão autoriza regeneração ampla, e-AllowWideRebuildnão autoriza reorg; comForceRebuild=false, o switch é redundante: o wrapper registra warning emwarnings, não pede a frase exata e mantémAllowWideRebuildConfirmed=false)-ConfirmWideRebuild(switch — usado em conjunto com-AllowWideRebuildpara dispensar oRead-Hostinterativo da frase de confirmação; destina-se a processos desanexados onde não há terminal disponível; proibido sem-AllowWideRebuild; o chamador é responsável por confirmar com o usuário humano com a frase exata antes de passar este parâmetro)-AllowCostlyBuildOptions(switch — único caminho autorizado para habilitar-CompileMains trueou-DetailedNavigation true; em modo interativo exige a frase exataentendo que estas opcoes podem ampliar muito o custo do build e aceito executar; em modo não-interativo requer-ConfirmCostlyBuildOptions; gate independente de-AllowWideRebuilde-AllowReorg)-ConfirmCostlyBuildOptions(switch — usado em conjunto com-AllowCostlyBuildOptions; proibido sem-AllowCostlyBuildOptions; o chamador é responsável por confirmar com o usuário humano com a frase exata antes de passar este parâmetro)-Configuration(String, opcional — valores válidos:Release,Debug,Performance Test; quando informado, emiteSetConfigurationimediatamente antes doBuildAll; quando omitido, a configuração ativa da KB é mantida sem alteração)
Categorias de resultado:
falha operacional com rejeicao MSBuild no log— Categoria B:executionEvidence.msBuildExitCode=0masbuildErrorspopulado;exitCode=48,msBuildCategoryBBlocked=true,operationalSubStatetipicamentebuild com errors do MSBuild — resultado não confiável; reproduzir linhaserror :ao usuário; não declararcompilou limpocompilou limpo—BuildAllconcluiu com exitCode 0 (classificado pelo wrapper, sem Categoria B), sem reorg detectada, stderr vazio após filtro de ruído estrutural conhecido e stdout sem padrões de erro após filtro de ruído estrutural conhecido em stdout (ver padrões abaixo); eventos pós-build registrados emkb_environment_post_build_event_hashes(ou benignos por som, sem registro) são informativos e não impedemcompilou limpo— verstdoutSignals.postBuildEventClassificationcompilou-mas-dll-destino-desatualizada— MSBuild concluiu com exit 0, mas oweb\binresolvido porkb_environment_web_dirspara o environment de deploy (deployment_environment_name+deployment_hosting_kindno metadata) não mostra publicação fresca (DLL de objeto ou*.configembin); verdeployBinFreshness/deployBinCheck/publicationFreshSinceBuildno JSON. Com-PostImportDeployValidationou-StrictDeployBinCheck, o wrapper usa exit 49; sem gate,exitCodeMSBuild permanece 0 mas não declarar validação deploy OK.GxNetCoreStartup.dllsozinha não dispara este statuscompilou com erros—BuildAllfalhou por erro de compilaçãoreorg necessária detectada—FailIfReorg=truebloqueou o build; reorg gerada mas não executada; usuário deve decidir o próximo passotimeout em KB grande— wrapper encerrou por timeout mas MSBuild pode ainda estar executando; distinguir timeout do invocador de falha real do MSBuild antes de concluir; usarWatch-GeneXusMsBuildLog.ps1com o PID do processo e o caminho do log para acompanhar a execução em andamento sem depender do chatKB inacessível—OpenKnowledgeBasefalhou antes do buildoperação concluída, pendente de confirmação funcional— exitCode 0, reorg não detectada, mas stderr não vazio após filtro de ruído estrutural, ou evento pós-build não registrado/não reconhecido (postBuildEventClassification.shouldDowngrade=true), ou marcador de conclusão não detectado; validação funcional depende de inspeção na IDE
Alternativa manual para processo já separado ou retomada após timeout: Em execução nova de
BuildAllouSpecifyGenerate, preferir-StartWatcherno próprio wrapper. UsarWatch-GeneXusMsBuildLog.ps1externamente apenas quando o processo já tiver sido iniciado em separado ou quando for necessário acompanhar uma execução ainda ativa após timeout do invocador. Se o chamador iniciarInvoke-GeneXusKbBuildAll.ps1como processo desanexado viaStart-Process pwsh,Read-Hostnão terá terminal disponível. Use-AllowReorg -ConfirmReorgjuntos — nunca redirecione stdin como workaround. O chamador é responsável por confirmar com o usuário humano antes de lançar o processo.Para obter timing por fase no JSON de resultado, defina um caminho para o log do monitor e conecte os dois scripts: passe
-MonitorLog <caminho>ao Watch e o mesmo<caminho>como-MonitorLogPathao build. O build parseia esse arquivo após terminar e populatiming.phasescom os timestamps de cada fase interna.
Padrão conhecido — ruído estrutural do
dotnet publishemGAM\Platforms\NetCore*(stdout): OBuildAllem environments .NET Core (NETPostgreSQL, NETCoreSQLServer e similares) dispara, na faseInicialização Integrada de Segurança, o comando:dotnet publish -nologo -v q -p:GenInit=false "C:\Program Files (x86)\GeneXus\GeneXus18\Library\GAM\Platforms\<NetCore*>\GxDeps.csproj" -o "C:\Program Files (x86)\GeneXus\GeneXus18\Library\GAM\Platforms\<NetCore*>"Quando o processo não roda elevado (ver Restrição Operacional de Leitura em
10-base-operacional-msbuild-headless.md), odotnet publishpode falhar comerror MSB3491ao tentar gravarPublishOutputs.<hash>.txtem\Library\GAM\Platforms\build\GxDeps\obj\net*\, ou com a varianteNuGet.targets(...): error : Access to the path ... is deniedao tentar gravar temporários sob\Library\GAM\Platforms\<NetCore*>\obj\. Esses caminhos ficam sobC:\Program Files (x86)\— área tratada como estritamente somente leitura pela skill por política explícita. Apesar do erro, a fase reportaSucesso, o GAM permanece registrado normalmente e o build prossegue sem efeito funcional na KB.
Invoke-GeneXusKbBuildAll.ps1filtra esse padrão antes de classificar o status. As linhas removidas ficam emstdoutFilteredNoisedo diagnóstico. Uma execução bem-sucedida cujo único padrão bloqueante em stdout seja esse ruído é classificada comocompilou limpo.Assinaturas do filtro:
- assinatura 1: linha contém
error MSB3491,is denied(EN) ouacesso negado(PT-BR), e caminho contendo\GeneXus\e\Library\GAM\Platforms\- assinatura 2: linha contém
NuGet.targets(...): error :,is denied(EN) ouacesso negado(PT-BR), e caminho contendo\GeneXus\e\Library\GAM\Platforms\Linhas que casem apenas alguns dos critérios (ex.:
MSB3491em projeto da KB,NuGet.targetsfora da árvore de instalação do GeneXus ouAccess deniedfora de\Library\GAM\Platforms\) não são filtradas — são diagnósticos legítimos.Remediação opcional (one-time, consultiva): quando pelo menos uma linha desse ruído for filtrada para
stdoutFilteredNoise,Invoke-GeneXusKbBuildAll.ps1(viascripts/GeneXusMsBuildGamPlatformsSupport.ps1) populaenvironmentRemediationHintsno diagnóstico JSON com caminhos derivados deresolvedPaths.GeneXusDirefetivo, a contabuildUserque executou o wrapper e comandosicaclssugeridos (conceder, verificar, reverter) sobre<GeneXusDir>\Library\GAM\Platforms. É ação única do usuário humano em terminal elevado — a skill nunca executaicaclsnem altera a instalação do GeneXus. Não recomenda elevar o build a cada execução; filtrar o ruído e classificar como limpo permanece o comportamento padrão aceitável. O hint é não bloqueante: não entra emwarnings, não alterastatusnemexitCode.
Evidência empírica acumulada (ruído GAM/NetCore): Coleta controlada em 2026-05-12, GeneXus 18 Up 14, em duas KBs distintas e dois environments cada (matriz 2×2):
KB Environment Generator MSB3491em stdoutwsEducacaoSpTesteNETPostgreSQL.NET Core presente wsEducacaoSpTesteNETFrameworkSQLServer.NET Framework ausente FabricaBrasil18NETPostgreSQL.NET Core presente FabricaBrasil18.Net Environment.NET Framework ausente O arquivo target
PublishOutputs.<hash>.txté literalmente o mesmo entre KBs distintas — é asset compartilhado da instalação do GeneXus, não da KB. A versão GAM no banco (4.1.5em ambas) permanece idêntica antes e depois, com ou sem elevação. Comparação elevado vs não-elevado emwsEducacaoSpTeste/NETPostgreSQLconfirmou que a falha dodotnet publishnão tem efeito funcional observável: stdout difere em uma única linha (a doMSB3491); todo o resto — versão GAM, warnings, fases, artefatos gerados emC:\KBs\<kb>\<env>\web\— é idêntico.Conclusão: o ruído é determinístico, originário da política de leitura-apenas da skill aplicada sobre
C:\Program Files (x86)\GeneXus\GeneXus18\Library\GAM\Platforms\, e sem consequência funcional. O filtro é seguro porque cada assinatura é ancorada simultaneamente no formato do erro, na mensagem de acesso negado e no caminho de instalação do GeneXus, não no padrão genéricoAccess denied.Observação sobre cobertura desta matriz (atualização 2026-05-20): os builds da matriz 2×2 acima foram limpos em modo headless sem PATH enriquecido — porque nenhum deles atingiu a fase
Atualização de configuração da webouDeveloperMenu Compilação. Quando essas fases são atingidas, builds headless sem PATH enriquecido com subdirs do GeneXus 18 falham com mensagem genéricaO sistema não pode encontrar o arquivo especificado(ou, em .NET Framework, a versão verbosegxexec ... Não foi possível encontrar uma parte do caminho). Ver nota "Padrão conhecido — subdirs do GeneXus 18 e PATH herdado em headless" abaixo. A política de enriquecimento aplicada pelos wrappers elimina esse modo de falha; a matriz histórica é preservada como evidência do estado das KBs em 2026-05-12.
Padrão conhecido — subdirs do GeneXus 18 e PATH herdado em headless: Tasks internas do MSBuild GeneXus invocam binários auxiliares (
gxexec,UpdConfigWeb,BuildService,Reor.exe) por nome, sem caminho absoluto, esperando subdirs do install já presentes em$env:PATH. A IDE GeneXus enriquece esse PATH implicitamente; um MSBuild lançado por wrapper externo herda apenas o PATH do shell do agente, que tipicamente não inclui esses subdirs. Sintomas: falha emDeveloperMenu Compilação para Default (.NET Framework)ouAtualização de configuração da web, comBuild All Task falhoueMsBuildExitCode=1.Os wrappers
Invoke-GeneXusKbBuildAll.ps1eInvoke-GeneXusKbSpecifyGenerate.ps1aplicam enriquecimento automático de$env:PATHapós resolver$resolvedGeneXusDir, com lista fixa: raizGeneXus18\,gxnet\,gxnet\bin\,gxnetcore\. Filtro porTest-Pathtolera instalações não-padrão. O resultado é registrado emobservedContext.pathEnrichmentdo JSON, comapplied(booleano),subdirsAddedesubdirsSkipped. Subdirs esperados ausentes geram warning emwarnings[].Evidência empírica (FabricaBrasil18, GeneXus 18 Up 14, 2026-05-20):
Rodada PATH Status exit MsBuildExitCode BuildAllDone Duração baseline default (sem GeneXus) compilou com erros45 1 false 90 s manual enriquecido pelo invocador compilou limpo0 0 true 261 s pós-fix enriquecido pelo próprio wrapper compilou limpo0 0 true (idem) Detalhes técnicos em
10-base-operacional-msbuild-headless.md, seção "Achado Empírico Sobre Subdirs Do GeneXus E PATH Em Headless".
Padrão conhecido — ruído estrutural do GeneXus 18 em stderr: O GeneXus 18 escreve exatamente 3 linhas
context [anonymous] 1:12 attribute component isn't definedno stderr durante oSpecifyAll— task executada internamente peloBuildAlle diretamente porInvoke-GeneXusKbSpecifyGenerate.ps1. O próprio GeneXus não conta isso como erro: stdout reporta "0 avisos, 0 erros". Evidência empírica acumulada: FabricaBrasil18 e wsEducacaoSpTeste em 2026-05-10, environments.Net Environment,NETFrameworkSQLServereNETPostgreSQL, sempre 3 ocorrências, mesma posição1:12, independente do conteúdo ou de alterações recentes na KB. Origem técnica rastreada:SpecifyAllinvocaGenexus.MsBuild.Tasks.dll, que referenciaArtech.Genexus.CommoneAntlr4.StringTemplate; o warning vaza do runtime de templates StringTemplate durante a montagem da changed objects list, antes de qualquer especificação real. A IDE absorve essa saída sem registrá-la noBuild.log; artefatos gerados em modo headless são equivalentes aos gerados pela IDE. Ambos os scripts filtram esse padrão antes de classificar o status — uma execução bem-sucedida cujo stderr contenha apenas esse ruído é classificada comocompilou limpo/specify e generate concluídos.
Invoke-GeneXusDbImpact.ps1
Gera o script de impacto de banco (ImpactDatabaseOnly) sem executar a reorganização.
Equivalente ao PreviewMode de importação: mostra o que mudaria no banco antes de
qualquer decisão de execução. Usar quando BuildAll reportar reorg necessária detectada
e o usuário quiser inspecionar antes de autorizar.
Parâmetros transversais: mesmos dos scripts anteriores.
Parâmetros específicos:
-Force(Boolean, defaultfalse— força geração do script mesmo que GeneXus ache desnecessário)-EnvironmentName(String, opcional — Environment a usar; se omitido, usa o ativo)
FromModeleModelsão propriedades públicas da task confirmadas por reflexão do assembly, mas sua semântica exata não foi validada empiricamente. Não emitir sem teste controlado que confirme o comportamento esperado.
Categorias de resultado:
impacto gerado— script de impacto produzido; caminho do artefato disponível para inspeçãonada a reorganizar— task concluiu sem gerar script de alteraçãoKB inacessível—OpenKnowledgeBasefalhou antes da taskoperação concluída, pendente de confirmação funcional— exitCode 0, mas o script de impacto ainda precisa ser inspecionado antes de qualquer decisão
Status: a implementar.
Invoke-GeneXusDbReorg.ps1
Executa o script de reorg já gerado (ReorganizeOnly), sem repetir o ciclo completo de
BuildAll. Usar quando ImpactDatabaseOnly já foi executado e inspecionado e o usuário
autoriza explicitamente a execução. Exige confirmação interativa obrigatória.
Parâmetros transversais: mesmos dos scripts anteriores.
Parâmetros específicos:
-DoCreate(Boolean, defaultfalse— setrue, cria também os objetos novos além de alterar os existentes)
Categorias de resultado:
reorg executada— script de impacto executado; banco alteradonada a reorganizar— nenhum script pendente para executarKB inacessível—OpenKnowledgeBasefalhou antes da taskfalha de reorg— execução do script falhou; banco pode estar em estado parcial
Status: a implementar após Invoke-GeneXusDbImpact.ps1 validado empiricamente.
ORQUESTRAÇÃO — PASSO A PASSO EXECUTÁVEL
Esta seção descreve o fluxo completo para executar Invoke-GeneXusKbBuildAll.ps1
com Watch-GeneXusMsBuildLog.ps1 em paralelo, sem bloquear a conversa com o usuário.
Por que processo desanexado
Invoke-GeneXusKbBuildAll.ps1 usa Start-Process internamente para o MSBuild e
Wait-Process para aguardar o resultado. Se chamado diretamente pelo agente via
PowerShell tool, bloqueia o agente durante todo o build — que pode durar minutos.
A solução é lançar o script como processo filho desanexado e usar run_in_background: true
no Wait-Process externo, liberando o agente para conversar com o usuário enquanto
o build corre.
Passo 1 — Preparar pastas e caminhos
$testDir = "C:\Dev\Knowledge\GeneXus-XPZ-Skills\Temp\xpz-build-<nome-descritivo>"
New-Item -Path $testDir -ItemType Directory -Force | Out-Null
$monitorLog = "$testDir\monitor.log"
$buildLog = "$testDir\build-all.log"
$buildStdout = "$testDir\build-proc-stdout.txt"
$buildStderr = "$testDir\build-proc-stderr.txt"
$testDirfica sobTemp\do repositório da skill — processos filhos têm permissão de escrita aqui.- Nunca usar
C:\Temp\ou pastas fora do repositório — processos desanexados não têm acesso. - Escolher um nome descritivo que identifique o build (ex.:
xpz-build-20260508-pos-import).
Passo 2 — Capturar dirs existentes antes de iniciar
$artifactBase = "C:\Dev\Knowledge\GeneXus-XPZ-Skills\Temp\xpz-msbuild-build"
$dirsBefore = @([System.IO.Directory]::GetDirectories($artifactBase))
O script cria um dir com GUID aleatório em $artifactBase. Capturar a lista antes
do início permite identificar o dir novo por diferença — sem depender de timestamp.
Passo 3 — Iniciar o build como processo desanexado
$scriptPath = "C:\Dev\Knowledge\GeneXus-XPZ-Skills\scripts\Invoke-GeneXusKbBuildAll.ps1"
$buildArgs = @(
'-NonInteractive', '-NoProfile', '-File', $scriptPath,
'-KbPath', 'C:\KBs\<nome-da-kb>',
'-WorkingDirectory', $testDir, # obrigatório — pasta já criada no passo 1
'-LogPath', $buildLog, # onde o JSON de resultado será gravado
'-MonitorLogPath', $monitorLog, # conecta com Watch para timing.phases
'-StartWatcher' # wrapper lança o watcher automaticamente
# adicionar '-AllowReorg', '-ConfirmReorg' apenas se reorg foi autorizada pelo usuário
)
$buildProc = Start-Process pwsh -ArgumentList $buildArgs `
-RedirectStandardOutput $buildStdout `
-RedirectStandardError $buildStderr `
-NoNewWindow -PassThru
-WorkingDirectory: pasta criada no passo 1 — não inventar outro caminho.-LogPath: onde o JSON de resultado será gravado ao final do build.-MonitorLogPath: mesmo caminho do log do monitor — obrigatório quando-StartWatcherestá presente.-StartWatcher: o wrapper disparaWatch-GeneXusMsBuildLog.ps1automaticamente antes do MSBuild; elimina o passo 5 do fluxo externo quando usado.-NoNewWindow: build roda invisível em segundo plano.-PassThru: retorna o objeto de processo com o PID.
Com
-StartWatcher, o Passo 5 (Watch externo) pode ser omitido — o wrapper já cuidou do lançamento. O Passo 4 (aguardar artifact dir) ainda é necessário quando se quer omsbuildLogpara fins de diagnose, mas não para o watcher em si.
Passo 4 — Aguardar o artifact dir aparecer
$artifactDir = $null
for ($i = 0; $i -lt 40; $i++) {
Start-Sleep -Milliseconds 500
$newDirs = @([System.IO.Directory]::GetDirectories($artifactBase) |
Where-Object { $dirsBefore -notcontains $_ })
if ($newDirs.Count -gt 0) { $artifactDir = $newDirs[0]; break }
}
if ($null -eq $artifactDir) {
# build falhou antes de criar o dir — ler stderr para diagnose
return
}
$msbuildLog = Join-Path $artifactDir "msbuild.stdout.log"
- O loop aguarda até 20 s (40 × 500 ms). Em hardware lento pode ser necessário aumentar.
- Usar diff de arrays (
$dirsBefore -notcontains $_), nunca indexar[0]diretamente no resultado doWhere-Object— quando há um único resultado, indexar retorna o primeiro caractere da string, não o item.
Passo 5 — Abrir Watch em janela visível
$watchScript = "C:\Dev\Knowledge\GeneXus-XPZ-Skills\scripts\Watch-GeneXusMsBuildLog.ps1"
Start-Process pwsh -ArgumentList @(
'-NoExit', # janela permanece aberta após o Watch terminar
'-NoProfile',
'-File', $watchScript,
'-ProcessId', $buildProc.Id,
'-LogPath', $msbuildLog, # msbuild.stdout.log dentro do artifact dir
'-MonitorLog', $monitorLog, # mesmo caminho que -MonitorLogPath do build
'-IntervalSeconds', '5' # default; diminuir só em testes curtos
)
- Sem
-NoNewWindowe sem redirect: Watch abre em janela nova visível ao usuário. -NoExit: a janela permanece aberta após Watch encerrar, para o usuário ler com calma e fechar manualmente.- Watch exibe o contador de silêncio in-place (sem scroll) e imprime uma nova linha apenas quando há conteúdo real (fase, alerta, início/fim).
- O arquivo
$monitorLogrecebe apenas linhas reais — não o contador de silêncio.
Passo 6 — Aguardar em background sem bloquear a conversa
# Este bloco deve ser executado com run_in_background: true no PowerShell tool.
# O agente fica disponível para conversar com o usuário enquanto o build corre.
# Quando Wait-Process retornar, o runtime notifica o agente automaticamente.
Write-Host "Build PID=$($buildProc.Id) | Watch aberto | aguardando..."
$buildProc | Wait-Process -Timeout 600 # 10 min; ajustar para KBs grandes
Write-Host "BUILD CONCLUIDO | exit=$($buildProc.ExitCode) | log=$buildLog"
Importante: o bloco inteiro (incluindo Wait-Process) deve estar em um único
comando com run_in_background: true. Não dividir em dois comandos separados.
Passo 7 — Ler o resultado quando notificado
Quando a notificação de conclusão chegar, ler o JSON com o Read tool (sem prompt de permissão):
Read tool → $buildLog (build-all.log)
Campos relevantes:
status— categoria de resultado (ver EXPECTED INTERFACE); com Categoria B costuma serfalha operacional com rejeicao MSBuild no logexitCode— código de saída classificado pelo wrapper (0 quandocompilou limpo/specify e generate concluídossem Categoria B; 48 quandomsBuildCategoryBBlocked=true; outros valores não nulos quando há impedimento ou falha); também é o exit code do processo. O valor bruto da task MSBuild aparece canonicamente emexecutionEvidence.msBuildExitCode. Nunca tratarexecutionEvidence.msBuildExitCode=0isolado como sucesso limpo quandoexitCode=48oumsBuildCategoryBBlocked=true.observedContext.MsBuildExitCode(PascalCase, dentro do contexto observado), quando presente, é contexto observado/compatibilidade e não substitui o campo canônico;msBuildExitCodetop-level, quando existir por compatibilidade transitória em algum wrapper, deve duplicar o valor canônico.msBuildCategoryBBlocked—truequando Categoria B rebaixou o resultado para exit 48operationalSubState— quando presente combuild com errors do MSBuild — resultado não confiável, reforça que o build não é entrega operacional limpabuildErrors/specifyErrors— listas no top-level (e espelhadas emstdoutSignalsquando aplicável) com linhaserror :classificadas; reproduzir ao usuário quando não vaziasblockingReasons— causas acionáveis; com Categoria B inclui resumo por estágio (BuildAll/SpecifyGenerate)executionEvidence— evidência bruta da execução (msBuildExitCode,msBuildFailed,wrapperExitCode, logs brutos);blockingReasonsdeve priorizar causas acionáveis e não repetir o exit code bruto quando uma causa específica já existirsummary— descrição legível do resultadotiming.msbuildDurationSeconds— duração do MSBuild em segundostiming.phases— lista de fases comname,start,end,durationSecondsobservedContext.ReorgDetected— se reorg foi detectadastdoutSignals— sinais estruturados de stdout:blockingPattern(primeiro padrão bloqueante detectado APÓS filtro de ruído estrutural, ounull),postBuildEvents(linhas capturadas na janelaExecutando eventos pos-construcao ...ate o próximo separador==========; em logs sem marcador, fallback parastart c:/start cmd; prefixo(commented)quando o GeneXus encenou o comando como comentado),buildWarnings(linhas de warning com posição; warningspmm00xxde versão de módulo são adicionalmente promovidos awarningstop-level — ver nota abaixo)stdoutFilteredNoise— ruído estrutural removido de stdout antes de classificar (ex: linhaserror MSB3491ouNuGet.targets(...): error :dodotnet publishemGAM\Platforms\NetCore*quando rodando sem elevação); quando o único conteúdo bloqueante em stdout for ruído filtrado, o build é classificado como limpoenvironmentRemediationHints— omitido quando não houve ruído GAM filtrado; quando presente, contémgamPlatformsWriteDeniedFilteredcomcondition,filteredLineCount,resolvedGeneXusDir,resolvedPlatformsPath,buildUser,summaryForUser,suggestedCommands(grant,verify,revert) e flagsoneTimeUserAction/skillDoesNotExecuteGrant/doesNotRecommendElevatedBuild. Oferta consultiva para silenciar o ruído de vez com permissão NTFS — não é warning, erro nem mudança de classificaçãostderrContent— linhas reais de stderr após remoção do ruído estrutural do GeneXus 18stderrFilteredNoise— ruído estrutural removido de stderr; quandostderrContentestá vazio estderrFilteredNoisetem conteúdo, o build é limpo e nenhuma recomendação de IDE deve ser emitidapostProcessingFailed/postProcessingError— quandotrue, o pós-processamento local falhou após oMSBuild; lerpostProcessingErrore o log bruto emexecutionEvidence/artifacts. ComexecutionEvidence.msBuildExitCode=0e marcas primárias no stdout (__BUILDALL_DONE__,__SPECIFY_DONE__,__GENERATE_DONE__ouobservedContextequivalente), não tratar comofalha operacionalnem inferir exit 90 só pelo terminal;exitCodeclassificado pode permanecer 0 comsummarydegradadonote— quando presente após falha de serialização, indica diagnóstico parcial; priorizarmsbuild.stdout.lognos artefatosbuildSignals— presente apenas nos objetos enxutos do build-all ($fallbackde serialização e$recoveryexterno) quando o JSON saiu parcial; não aparece no diagnóstico completo. Carrega adianteReorgDetected/ErrorCount/PostBuildEventsjá computados, comCompleteindicando se o bucket é integral (true⇒ confiar e não reabrir o log;false⇒ parcial,null≠0/[]). Ver "Pós-processamento resiliente"
Promoção de warnings
pmm00xx(versão de módulo) awarningstop-level: Warnings GeneXus de famíliapmm00xx(ex.:pmm0003"módulo deve ser atualizado para versão N",pmm0045"version conflict") sinalizam estado da KB que precisa de atenção do usuário — tipicamente resolvido viaUpdate Modulesna IDE. ComobuildWarningsé lista interna que o usuário raramente inspeciona, esses warnings são adicionalmente surfacados emwarnings(top-level) do diagnóstico, com texto orientativo:
- Caso geral:
Alerta de versao de modulo (pmm00xx): <mensagem original>. Resolver via 'Update Modules' na IDE.- Caso
pmm0045(inversão de versão — módulo satélite exige versão MAIS NOVA do módulo principal do que a instalada): texto adicional explicando que pode exigir update do GeneXus instalado ou downgrade de módulos da KB; inspecionar viaUpdate Modulesna IDE.A promoção é somente para visibilidade — não muda classificação de status (warnings continuam sendo warnings, não viram erros). O build pode ser
compilou limpoouspecify e generate concluídosmesmo compmm00xxpresentes.
Modo desacoplado (opt-in, build longo)
O fluxo padrão acima (processo desanexado + Watch em janela visível) ainda acopla o
build à console/sessão do agente: fechar acidentalmente a janela do Watch, ou a janela-pai
do processo de fundo, derruba o grupo inteiro (wrapper + MSBuild + GeneXus) — matando um
BuildAll longo no meio, sem erro no log. O paliativo da própria janela (título e aviso
NÃO FECHAR impressos por Watch-GeneXusMsBuildLog.ps1) reduz o acidente humano, mas
não impede o fechamento.
Para build esperado longo (ex.: KB grande, Rebuild All, pós-import amplo) ou que vá
rodar em segundo plano enquanto o agente conversa, há o modo desacoplado via
Start-GeneXusKbBuildDetached.ps1. Ele registra uma Tarefa Agendada one-shot que executa
Invoke-GeneXusKbBuildAll.ps1 fora da console e do job da sessão do agente: fechar
qualquer janela ou encerrar o app não toca o build.
Não é o default. O agente propõe este modo quando detecta o gatilho (build longo ou em background), apresenta o trade-off — perde a janela de progresso ao vivo, ganha robustez a fechamento — e só o usa por decisão consciente do usuário. Build curto ou com o usuário acompanhando ao vivo: manter a janela visível padrão.
Fluxo:
- Confirmar com o usuário a escolha pelo modo desacoplado (e, se houver reorg/rebuild,
obter as frases de confirmação antes, pois a tarefa não tem terminal interativo —
repassar
-AllowReorg -ConfirmReorg/-AllowWideRebuild -ConfirmWideRebuildconforme o caso). - Lançar (o orquestrador retorna imediatamente, sem bloquear a conversa):
$scriptPath = "C:\Dev\Knowledge\GeneXus-XPZ-Skills\scripts\Start-GeneXusKbBuildDetached.ps1"
& $scriptPath `
-KbPath 'C:\KBs\<nome-da-kb>' `
-WorkingDirectory "C:\Dev\Knowledge\GeneXus-XPZ-Skills\Temp\xpz-build-<descritivo>" `
-LogPath "C:\Dev\Knowledge\GeneXus-XPZ-Skills\Temp\xpz-build-<descritivo>\build-all.log" `
-EnvironmentName '<env de deploy quando kb_environment_count > 1>' `
-ParallelKbRoot '<raiz da pasta paralela>'
# -SentinelPath default: <LogPath>.sentinel
O JSON retornado traz
status: build desacoplado disparado,taskName,sentinelPath,logPatheartifactBaseDir. GuardarsentinelPathelogPath.Espera por dois sinais (nunca só a sentinela): prefira o helper
scripts/Wait-GeneXusKbBuildDetached.ps1 -SentinelPath <...> -TaskName <...>(rodar emrun_in_background), que encapsula a lógica abaixo e retornaoutcome(concluido/falha-anomala/timeout) com a margem de corrida e o timeout tratados. Quando feito à mão, combinar:- (a) sentinela em
sentinelPathcom{ "done": true, "exitCode": <n>, "logPath": "<...>", "logExists": <bool>, "error": "<msg ou vazio>", "stdoutPath": "<...>", "stderrPath": "<...>" }= conclusão normal:logExists=true→ o wrapper concluiu e gravou o JSON de resultado emlogPath(caminho normal).logExists=falsecomerrorpreenchido → o wrapper falhou antes de escrever o log; lererrore os arquivosdetached-payload-error.log/detached-payload-stderr.logno WorkingDirectory para diagnóstico (o payload não mascara mais a falha como exit cego).
- (b) heartbeat da tarefa via
Get-ScheduledTask -TaskName <taskName>— se a tarefa parou de executar (State ≠Running) ou sumiu e a sentinela continua ausente após uma curta margem de corrida, é falha anômala (kill abrupto / OOM / estouro de-ExecutionTimeLimitantes dofinally): lererror/stderrPath. Pollar só a existência da sentinela deixaria a espera presa para sempre num kill duro — daí o heartbeat. (A margem de corrida cobre o instante normal entre a tarefa deixar de estarRunninge ofinallyescrever a sentinela.)
Para progresso ao vivo enquanto corre, ler o
msbuild.stdout.logdo artifact dir novo sobartifactBaseDir(diff de diretórios, como no Passo 4 do fluxo padrão).- (a) sentinela em
Quando a sentinela indicar conclusão com
logExists=true, ler o JSON completo delogPathcom a ferramentaReade classificar o resultado exatamente como no fluxo padrão (mesmas categorias, mesma leitura deexitCode/msBuildCategoryBBlocked/buildErrors). A Tarefa Agendada roda sem janela (console oculto —-WindowStyle Hidden; não há janela para fechar acidentalmente) e se auto-remove ao fim;timing.phasesfica vazio neste modo (sem watcher).
Robustez vs. limites: o modo desacoplado sobrevive a fechar janela e a encerrar o app do agente. Não sobrevive a logoff do Windows (a Tarefa Agendada é registrada com
LogonType Interactive, rodando sob a sessão interativa do usuário logado) nem a reboot — coerente com o cenário-alvo (o incidente é fechar janela/app, não deslogar no meio do build). O modoS4U/Password (que rodaria deslogado) não é oferecido, por decisão consciente: exigiria armazenar/gerenciar credenciais e o build depende do contexto interativo do usuário (instalação do GeneXus, drives mapeados, perfil).
Observações críticas
- Não usar
C:\Temp\para nenhum arquivo: processos filhos desanexados não têm acesso. - Não bloquear a conversa com
Wait-Processsemrun_in_background: true. -ConfirmReorgsem-AllowReorgé bloqueado pelo script (exit 46) — nunca passar um sem o outro.-ConfirmReorgsubstitui oRead-Hostinterativo, mas não dispensa a confirmação do usuário humano — obtê-la antes de lançar o processo.- Ler resultado com
Readtool, não comPowerShell(Get-Content ...)— evita prompt desnecessário. - Lançamento elevado (
Start-Process -Verb RunAs): quando o build for disparado com elevação UAC para experimento controlado, não confiar emWait-Processsobre o objeto retornado porStart-Process -PassThru— esse PID pode ser o broker/launcher do UAC, não opwshelevado real.Wait-Processretorna prematuramente quando o broker termina, deixando o build ainda em execução. Estratégia confiável: polling doLogPath(arquivo final do wrapper) — esse arquivo só aparece quando o script termina, tanto no caminho de sucesso quanto no de falha (status: falha operacional); aguardar a existência e a estabilidade do tamanho do arquivo. Cenário válido apenas para experimentos controlados —-Verb RunAsnão é fluxo regular da skill.
WORKFLOW
- Reler 10-base-operacional-msbuild-headless como referência de infraestrutura antes de qualquer operação
- Confirmar que o ambiente já passou por probe (
Test-GeneXusMsBuildSetup.ps1) ou realizar o probe agora — esta skill não substitui a validação de ambiente - Confirmar que
C:\Program Files (x86)será tratada como somente leitura - Identificar o objetivo:
- verificação pós-import cirúrgico →
Invoke-GeneXusKbSpecifyGenerate.ps1 - validação completa incluindo compilação →
Invoke-GeneXusKbBuildAll.ps14a. Se o objetivo forInvoke-GeneXusKbSpecifyGenerate.ps1, avaliar sinais de alteração estrutural no contexto do import recente: importedItemsdo log de import contém qualquer objetoAttribute:→ sinal presente- usuário mencionou mudança de tamanho, tipo, precisão ou subtipo de atributo → sinal presente
- execução anterior nesta sessão retornou
reorg detectada ou executada→ sinal presente Se qualquer sinal estiver presente: - exibir aviso: "Esta execução pode disparar reorganização real de banco de dados, pois o import recente contém alterações estruturais em atributo. A task SpecifyAll do GeneXus executa reorg internamente quando o modelo tem mudanças estruturais pendentes. Para prosseguir, confirme com a frase exata:"
entendo que haverá reorg e concordo que prossiga- aguardar a frase exata do usuário — não aceitar paráfrases ou confirmações genéricas
- só então executar o script
4b. Se o usuário informar
-Configuration: - confirmar que o valor é
Release,DebugouPerformance Test - emitir
SetConfigurationcomo step imediatamente anterior aoBuildAll - registrar o valor emitido no log e no diagnóstico
4b. Environment de validação/deploy (objetivo A): antes de
BuildAll/SpecifyGenerate, confirmarkb_environment_countemkb-source-metadata.md(via-ParallelKbRootou-KbMetadataPath). Sekb_environment_count> 1:-EnvironmentNameobrigatório oudeployment_environment_namepreenchido no metadata (setup). Se campos ausentes, bloquear e orientarxpz-kb-parallel-setup+Set-XpzKbSourceMetadataDeployment.ps1. Se a frente exigir objetivo B (opt-in), orientar Build na IDE nos environments secundários ao encerrar — não loop headless automático porkb_environment_names.
- verificação pós-import cirúrgico →
- Validar explicitamente
KbPath,GeneXusDir,MsBuildPath,WorkingDirectory,LogPathe existência deGenexus.Tasks.targets - Resolver
GeneXusDireMsBuildPathpor ordem explícita de precedência e fallback, registrando origem e descarte de candidatos - Se o objetivo for
BuildAllcom reorg autorizada (-AllowReorg):- apresentar ao usuário o que reorg significa neste contexto
- exigir confirmação explícita antes de prosseguir
- só então emitir
FailIfReorg=falseeDoNotExecuteReorg=false7a. Se o objetivo envolver-ForceRebuild=true(emBuildAllouSpecifyGenerate): - apresentar ao usuário o que isso significa neste contexto: equivale a
Rebuild Allda IDE, regenera TODOS os objetos da KB independentemente de mudança, pode levar horas e regenerar centenas/milhares de objetos em KB grande - exigir a frase exata
entendo que isto pode regerar a KB inteira e aceito o custo— não aceitar paráfrases ou confirmações genéricas - só então passar
-AllowWideRebuild(e-ConfirmWideRebuildse em processo desanexado, após obter a frase do usuário humano) - gate independente do gate de reorg:
-AllowReorgnão autoriza-ForceRebuild=true, e-AllowWideRebuildnão autoriza reorg
- Executar o script escolhido seguindo a seção ORQUESTRAÇÃO — PASSO A PASSO EXECUTÁVEL
(para
BuildAll: processo desanexado + Watch em janela visível +run_in_background; ou, para build longo/em segundo plano após o usuário optar conscientemente, o modo desacoplado viaStart-GeneXusKbBuildDetached.ps1+ espera por sentinela + heartbeat (helperWait-GeneXusKbBuildDetached.ps1) — ver subseção própria) e capturar:exitCode,msBuildCategoryBBlocked,operationalSubStatebuildErrorsouspecifyErrorsno top-level do JSON (quando existirem)executionEvidence.msBuildExitCodeeblockingReasons- resumo de
stdout - resumo de
stderr - caminho do
.msbuildtemporário - caminho do log
- Ler
exitCode,msBuildCategoryBBlockedebuildErrors/specifyErrorsno JSON antes de classificar. ComexitCode=48oumsBuildCategoryBBlocked=true, classificar comofalha operacional com rejeicao MSBuild no log, reproduzir linhaserror :ao usuário e não usarcompilou limponemspecify e generate concluídos. Caso contrário, escanear stdout e stderr por padrões de erro e risco antes de classificar, inclusive quandoexecutionEvidence.msBuildExitCode=0eexitCode=0:- padrão bloqueante máximo:
Reorganizaem stdout → statusreorg detectada ou executada; não declarar sucesso; informar ao usuário e aguardar instrução - eventos pós-build: linhas dentro da janela
Executando eventos pos-construcao ...ate o próximo separador==========em stdout; se o marcador não existir, fallback para linhasstart c:oustart cmd. Classificados contrakb_environment_post_build_event_hashesdo environment ativo (kb-source-metadata.md): registrado = esperado (informativo, não rebaixa); não registrado/não reconhecido = rebaixa por cautela;REMcomentado é inerte; sem registro para o environment, player de som (SoundPlayer/PlaySync/.wav) é benigno e o resto rebaixa. Registrar viaxpz-kb-parallel-setup(Register-GeneXusKbPostBuildEvents.ps1); verstdoutSignals.postBuildEventClassification - stderr não vazio: qualquer conteúdo → registrar como warning; impede
specify e generate concluídos - demais padrões relevantes:
Access denied,error MSB,: error,FAILED, stack traces de exceção - carve-out para ruído estrutural GAM/NetCore: linhas que casam uma das assinaturas conhecidas (
error MSB3491ouNuGet.targets(...): error :) junto comis denied/acesso negadoe caminho contendo\GeneXus\e\Library\GAM\Platforms\são removidas de stdout antes desta varredura e listadas emstdoutFilteredNoise; padrões legítimos deAccess deniedem qualquer outro contexto permanecem bloqueantes - se encontrados: registrar no diagnóstico e usar
operação concluída, pendente de confirmação funcionalem lugar decompilou limpoClassificar então o resultado em uma das categorias definidas em EXPECTED INTERFACE 9a. QuandoenvironmentRemediationHints.gamPlatformsWriteDeniedFilteredestiver presente no JSON: - apresentar ao usuário
summaryForUsere os três comandos emsuggestedCommandscomo nota opcional para eliminar o ruído GAM de forma permanente - deixar claro que é execução única pelo usuário em terminal elevado e que a skill não executa
icacls - não promover a
warnings, não reclassificar o build, não sugerir build elevado recorrente nem reabertura da IDE só por causa desse hint
- padrão bloqueante máximo:
- Quando o resultado for
reorg necessária detectada:- informar ao usuário sem dramatizar
- apresentar as três opções:
a. inspecionar primeiro com
Invoke-GeneXusDbImpact.ps1— gera o script de impacto para o usuário ver o que mudaria no banco b. autorizar reorg diretamente: via-AllowReorgemBuildAllou viaInvoke-GeneXusDbReorg.ps1após inspeção prévia c. abrir na IDE para decidir - aguardar instrução explícita
- se o usuário escolher
Invoke-GeneXusDbImpact.ps1: executar, apresentar resultado e caminho do script; só prosseguir para reorg após nova instrução explícita do usuário - se o usuário escolher
Invoke-GeneXusDbReorg.ps1: exigir confirmação interativa mesmo queImpactDatabaseOnlyjá tenha rodado na mesma sessão
- Recomendar reabertura da KB na IDE somente se houver warning ou efeito colateral
detectado no build (ex: extensão ausente,
Access denied, stderr não vazio), ou se o contexto indicar que o objetivo é validar a aplicação em execução; não mencionar IDE nem URL quando o pedido foi apenas "faça um build" e o resultado foi limpo - Não declarar sucesso funcional apenas por
exitCode = 0nem porexecutionEvidence.msBuildExitCode = 0quandoexitCode=48oumsBuildCategoryBBlocked=true
QUALITY CHECKLIST
- A skill foi tratada como capacidade operacional validada, com uso controlado
-
C:\Program Files (x86)permaneceu estritamente somente leitura - Ambiente validado por probe antes do build
-
KbPath,GeneXusDir,MsBuildPath,WorkingDirectoryeLogPathforam explicitados - Antes de abrir a KB por MSBuild em
BuildAllouSpecifyGenerate, o bloqueio preventivo de concorrência por KB foi executado; semsBuildConcurrency.status=blockedouexitCode=46, a rodada foi abortada e o conflito foi reportado ao usuário, sem tentar enfileirar nem aguardar - Houve monitoramento legível: janela visível (
-StartWatcher) ou modo desacoplado (Start-GeneXusKbBuildDetached.ps1commsbuild.stdout.log+ arquivo-sentinela); nenhuma execução sem monitoramento, salvo justificativa registrada (watcherContext.watcherLaunched: false) - O modo desacoplado, quando usado, foi proposto pelo agente (build longo/em segundo plano) e escolhido por decisão consciente do usuário — não acionado como default; reorg/rebuild tiveram as frases de confirmação obtidas antes do lançamento (tarefa sem terminal interativo)
- Quando o objetivo era
Invoke-GeneXusKbSpecifyGenerate.ps1, os sinais de alteração estrutural do import recente foram avaliados antes de executar - Quando havia sinal de alteração estrutural, a confirmação com a frase exata foi exigida e obtida antes de executar
-
FailIfReorg=truefoi mantido como default emBuildAll, salvo instrução explícita - Reorg só foi autorizada após confirmação explícita do usuário
-
-ForceRebuild=true(equivalente aRebuild All) só foi usado mediante pedido explícito do usuário, com aviso do custo apresentado e frase exataentendo que isto pode regerar a KB inteira e aceito o custoobtida antes de passar-AllowWideRebuild -
-CompileMains=trueou-DetailedNavigation=truesó foram usados mediante pedido explícito do usuário, com aviso do significado/custo apresentado e frase exataentendo que estas opcoes podem ampliar muito o custo do build e aceito executarobtida antes de passar-AllowCostlyBuildOptions - Quando
reorg necessária detectada, as três opções foram apresentadas ao usuário - Quando
reorg detectada ou executada(pós-SpecifyAll), o resultado foi apresentado ao usuário sem ser classificado como sucesso -
Invoke-GeneXusDbImpact.ps1foi executado antes deInvoke-GeneXusDbReorg.ps1quando o objetivo era inspecionar o impacto -
Invoke-GeneXusDbReorg.ps1recebeu confirmação interativa explícita, mesmo quando precedida deImpactDatabaseOnly -
stdout,stderr,exitCode,.msbuilde log foram registrados -
msBuildCategoryBBlocked,operationalSubStateebuildErrors/specifyErrorsno top-level do JSON foram lidos antes de declarar sucesso; comexitCode=48, a rodada foi tratada como Categoria B e as linhaserror :foram reproduzidas ao usuário - Com
spc0150…only allowed in proceduresemTransactionEvents, foi aplicado o anti-padrãotransaction-event-attribute-assignment-rejectede o Catálogo 2 em xpz-builder/responsibilities-by-type/transaction.md — atribuição a atributo da transação noEventnão é correção válida -
executionEvidence.msBuildExitCodefoi registrado como local canônico do valor bruto da task MSBuild;msBuildExitCodetop-level, quando existir, foi tratado apenas como compatibilidade transitória e duplicação do valor canônico -
observedContext.pathEnrichmentregistrou o enriquecimento preventivo doPATH(applied,subdirsAdded,subdirsSkipped) - O resultado foi classificado em categoria explícita
- Sucesso operacional foi separado de confirmação funcional
- Quando a frente foi descrita por fluxo funcional ("o objeto que X", "a tela que abre ao Y", "o objeto chamado quando Z") em vez de referência direta ao nome, foi confirmado que o objeto em
importedItemsé o alvo executado pelo fluxo descrito antes de declarar a frente encerrada — independente do tipo de objeto - Quando erros C# como
CS1010/CS1513sugeriram truncamento de.csgerado, o arquivo referenciado foi inspecionado antes de atribuir a falha ao XML, e qualquer regeneração ampla preservou o gate de-ForceRebuild=true - Quando o contexto for handoff de import OK com evento que não surte efeito, o
.csgerado foi inspecionado pelo nome do evento após build/SpecifyGenerate; foi distinguido mecanismo (b) (handler ausente/vazio — strip por DCE, correção no source conforme02) de falha de build e de mecanismo (a) (rejeição na importação — handoff paraxpz-msbuild-import-export, sem tratar.cscomo causa primária) - Quando o sintoma for Transaction (“rule não dispara” ou valor não chega no browser) após import OK com geração disponível, o
.csweb foi resolvido antes comscripts/Resolve-GeneXusGeneratedCsPath.ps1(ou wrapper local) a partir dekb_environment_web_dirs; ocsPathresolvido foi usado emscripts/Find-CsAttributeAssignments.ps1(-CsPathabsoluto,-Attribute,-AsJson); caminho, fonte da resolução, cópias por método,AssignAttrietripletDetected/cascadeOrderforam considerados antes de concluir -
watcherContext.watcherLaunchedfoi verificado no JSON de resultado; sefalse, a ausência foi documentada e justificada explicitamente - Quando
environmentRemediationHintsestiver presente, a ofertaicaclsfoi apresentada como consultiva e opcional, sem confundir com warning nem com falha de build -
kb_environment_countedeployment_environment_nameforam lidos do metadata (ou-EnvironmentNameexplícito) antes do build de validação - Com
kb_environment_count> 1,-ParallelKbRoot/-KbMetadataPathfoi passado e o environment de deploy foi resolvido -
ActiveEnvironmentno JSON foi comparado ao environment de validação resolvido antes de declarar validação deploy OK - Quando a frente exigiu objetivo B (opt-in): deploy validado (A) e Build na IDE nos environments secundários que a frente cobre — ou headless repetido documentado como exceção
- Validação deploy pós-import usou
-PostImportDeployValidation(ou-StrictDeployBinCheck) comdeployment_hosting_kinde paths resolvidos porkb_environment_web_dirsno metadata;deployBinFreshness/deployBinCheck/publicationFreshSinceBuildforam lidos — não declarar deploy OK comcompilou-mas-dll-destino-desatualizadaou exit 49; warning de sentinela Core (GxNetCoreStartup.dllvelho) não substitui gate - Build limpo rebaixado a
operação concluída, pendente de confirmação funcionalpor motivo benigno (evento pós-build como sino de fim de build, ruído em stderr) não suprimiu-PostImportDeployValidation: o gate decide por sucesso operacional (exitCode0 + marcador de conclusão do build), não pela string de status; só falha real (Categoria B, reorg, timeout, KB inacessível, que derrubamexitCode) pula o gate
CONSTRAINTS
- Ao interpretar
exitCodedo processo ou do JSON (46,47,49,50,40–45,48, …), consultarscripts/msbuild-exit-codes.catalog.json— especialmente o anexocauses[]do 46, exit 49 (deployBinFreshness) e exit 50 (-LogPathapontando para diretório existente); não inferir causa só pelo número no terminal - NEVER gravar qualquer artefato em
C:\Program Files (x86) - NEVER executar
icaclsnem qualquer concessão NTFS na instalação do GeneXus — apenas oferecer comandos emenvironmentRemediationHintspara o usuário executar uma vez, por conta própria, se quiser silenciar o ruído GAM filtrado - NEVER recomendar elevar o build MSBuild a cada execução como substituto do filtro de ruído GAM; a única elevação mencionada é terminal administrativo one-time para o usuário rodar
icaclssugerido - NEVER executar
BuildAllouSpecifyGeneratesem monitoramento legível — janela visível (-StartWatcher) ou modo desacoplado (Start-GeneXusKbBuildDetached.ps1, commsbuild.stdout.log+ arquivo-sentinela). A janela visível é o fluxo padrão; o modo desacoplado é opt-in consciente do usuário sob conselho do agente (build longo ou em segundo plano), nunca acionado em silêncio. Ausência total de monitoramento (nem janela, nem sentinela) só com justificativa operacional explícita e documentada, declarada ao usuário com base emwatcherContext.watcherLaunched: falseno JSON - NEVER chamar MSBuild para
BuildAllouSpecifyGeneratequando o preflightmsBuildConcurrencyconfirmarMSBuild.exeem execução para a mesma KB; abortar com exit 46 e reportar o processo conflitante - NEVER executar reorg sem autorização explícita do usuário
- NEVER emitir
FailIfReorg=falseimplicitamente — sempre explicitar quando e por quê - NEVER passar
-ConfirmReorgsem-AllowReorg— combinação bloqueada por política (exit 46) - NEVER usar
-ConfirmReorgsem ter obtido confirmação explícita do usuário humano antes de lançar o processo — o parâmetro muda o canal de confirmação, não dispensa a confirmação - NEVER passar
-ForceRebuild truesem-AllowWideRebuild— combinação bloqueada por política (exit 46) tanto emInvoke-GeneXusKbBuildAll.ps1quanto emInvoke-GeneXusKbSpecifyGenerate.ps1 - NEVER passar
-ConfirmWideRebuildsem-AllowWideRebuild— combinação bloqueada por política (exit 46) - NEVER passar
-CompileMains trueou-DetailedNavigation truesem-AllowCostlyBuildOptions— combinação bloqueada por política (exit 46) tanto emInvoke-GeneXusKbBuildAll.ps1quanto emInvoke-GeneXusKbSpecifyGenerate.ps1 - NEVER passar
-ConfirmCostlyBuildOptionssem-AllowCostlyBuildOptions— combinação bloqueada por política (exit 46) - NEVER usar
-ConfirmCostlyBuildOptionssem ter obtido a frase exataentendo que estas opcoes podem ampliar muito o custo do build e aceito executardo usuário humano antes de lançar o processo - NEVER passar
-ForceRebuild trueem fluxo pós-import cotidiano nem como "validação completa automática" —BuildAllincremental (sem-ForceRebuild) é o passo correto - NEVER usar
-ConfirmWideRebuildsem ter obtido a frase exataentendo que isto pode regerar a KB inteira e aceito o custodo usuário humano antes de lançar o processo — o parâmetro muda o canal de confirmação, não dispensa a confirmação - NEVER aceitar paráfrases ou confirmações genéricas no lugar da frase exata de confirmação de regeneração ampla
- NEVER depender de
GeneXus Servercomo base operacional desta skill - NEVER tratar
exitCode = 0isolado como confirmação funcional - NEVER classificar como
compilou limpoquando stdout ou stderr contiver padrões de erro (Access denied,error MSB,: error,FAILED, stack traces) fora do ruído estrutural GAM/NetCore documentado, mesmo que exitCode = 0 - NEVER ignorar
exitCode=48(msBuildCategoryBBlocked=true) — Categoria B:executionEvidence.msBuildExitCode=0com linhaserror :embuildErrors/specifyErrorsno JSON; verscripts/msbuild-exit-codes.catalog.jsone Categorias A/B emxpz-msbuild-import-export/SKILL.md - NEVER classificar como
specify e generate concluídosquando stdout contiver padrãoReorganiza— o status correto éreorg detectada ou executada - NEVER tratar stderr não vazio como irrelevante — qualquer conteúdo em stderr deve ser registrado como warning e impede classificação como
specify e generate concluídos - NEVER chamar
Invoke-GeneXusKbSpecifyGenerate.ps1quando houver sinal de alteração estrutural de atributo no import recente sem a confirmação explícita do usuário com a fraseentendo que haverá reorg e concordo que prossiga - NEVER aceitar paráfrases ou confirmações genéricas no lugar da frase exata de confirmação de reorg
- NEVER executar
Invoke-GeneXusDbReorg.ps1sem confirmação interativa explícita do usuário, mesmo quandoImpactDatabaseOnlyjá foi executado na mesma sessão - NEVER emitir
FromModelouModelemImpactDatabaseOnlysem validação empírica prévia do comportamento desses parâmetros nesta instalação - NEVER emitir
SetConfigurationimplicitamente ou inferir o valor de configuração desejado - ABORT se
KbPath, versão,Environmentde validação/deploy ou destino de logs estiverem ambíguos - NEVER executar
BuildAll/SpecifyGeneratede validação pós-import em KB comkb_environment_count> 1 sem-EnvironmentNameresolvido (parâmetro oudeployment_environment_nameno metadata) — o wrapper bloqueia (exit 46) - NEVER tratar
compilou limpocomo prova de que o IIS/self-host refletiu o import quandoActiveEnvironmentdivergir dedeploymentEnvironmentContext.validationEnvironmentResolved - NEVER declarar validação deploy OK quando
statusforcompilou-mas-dll-destino-desatualizada,deployBinFreshness=stale,publicationFreshSinceBuild=falseouexitCode=49— investigardeployBinCheck.interpretation,objectDllMaxWriteTime/configMaxWriteTimee paths resolvidos porkb_environment_web_dirs; não usarGxNetCoreStartup.dllsozinha como prova de publicação - ABORT se não houver ambiente controlado compatível com a fase solicitada