/** * Task Contract: contrato formal de UMA tarefa executável. * * Antes deste módulo, um nó do grafo (`GraphNode`) carregava só a mecânica de * execução (dependências, retry, timeout, tokenBudget). O que a tarefa PRECISA * entregar (objetivo, saída esperada, critérios de aceite verificáveis, teto de * custo) vivia implícito no template do planner ou no prompt. * * O contrato torna isso explícito e verificável: o Commander gera um contrato * por nó, o Context Resolver monta o contexto mínimo a partir dele, e a * Verification Engine decide VERIFIED/FAILED comparando o artefato produzido * contra `acceptance` + `verification`. Nada aqui depende de LLM: é o núcleo * determinístico exigido pela arquitetura (regra "Deterministic Core"). * * Compatibilidade: `GraphNode` continua sendo a unidade do scheduler. O * contrato é anexado em `node.metadata.contract` e lido por quem souber dele; * grafos antigos (sem contrato) seguem executando pelo caminho pré-contrato. */ import type { ArtifactKind, GraphNode } from '../types.js'; import type { ToolPermission } from '../tools/registry.js'; /** * Modo de execução adaptativo. Determina QUANTO runtime a tarefa merece: * direct : 1 chamada de modelo, sem grafo, sem avaliação pesada. * assisted : commander decide + 1 especialista executa. * orchestrated : grafo completo com verificação. * autonomous : grafo + healing + replan + verificação final. */ export type ExecutionMode = 'direct' | 'assisted' | 'orchestrated' | 'autonomous'; export declare const EXECUTION_MODES: ExecutionMode[]; export declare function isExecutionMode(value: string): value is ExecutionMode; /** Nível hierárquico de quem executa a tarefa (LEVEL 0/1/2 da arquitetura). */ export type AgentRole = 'commander' | 'specialist' | 'worker'; export declare const AGENT_ROLES: AgentRole[]; export type TaskPriority = 'low' | 'normal' | 'high' | 'critical'; /** * Verificação que roda SEM modelo nenhum. É o que separa "o agente disse que * terminou" de "existe evidência de que terminou". * * `command` fica de fora de propósito: executar comando arbitrário vindo de um * plano gerado é superfície de ataque. Comandos passam pela ToolRegistry, que * já aplica permissão/sandbox/Policy Engine. */ export type DeterministicCheck = { kind: 'artifact-valid'; message?: string; } | { kind: 'min-size'; bytes: number; message?: string; } /** * `wholeWord` exige fronteira de palavra em volta do termo. * * Existe porque marcador e palavra se confundem por substring: `not-contains` * de `"TODO"` (case-insensitive por default) reprovava qualquer artefato em * português que dissesse "todos". Medido: um relatório de segurança correto * foi recusado duas vezes por "saída sem TODO (zero stub/checklist)", tendo * como única ofensa a frase "todos os endpoints". */ | { kind: 'contains'; text: string; caseSensitive?: boolean; wholeWord?: boolean; message?: string; } | { kind: 'not-contains'; text: string; caseSensitive?: boolean; wholeWord?: boolean; message?: string; } | { kind: 'matches'; pattern: string; flags?: string; message?: string; } | { kind: 'json-field'; field: string; message?: string; } | { kind: 'file-exists'; path: string; message?: string; } /** * Groundedness: a fração de caminhos citados cujo LUGAR existe no projeto. * Pega quem inventou o layout sem reprovar quem propôs arquivo novo num * diretório real. Sem referência nenhuma no texto o check fica UNKNOWN — * ausência de sinal não é aprovação. */ | { kind: 'references-exist'; minRatio?: number; message?: string; } /** * O comando terminou com exit code 0. * * Existe para o único caso em que o runtime tem um exit code de verdade para * conferir: o artefato `test-run` da tool `project.test`. É o primeiro check * determinístico que fala de uma EXECUÇÃO e não do texto de um artefato, e a * regra é a mais estrita da lista: exit code ausente é `unknown` (não medi), * nunca `pass`. Um check de execução que aprova por ausência de evidência * seria pior que a métrica derivada de artefato que ele veio substituir. */ | { kind: 'exit-zero'; message?: string; }; export interface AcceptanceCriterion { id: string; description: string; /** * deterministic: decidido por `check` sem modelo. * semantic: exige um juiz (modelo ou humano); sem juiz configurado o critério * fica UNKNOWN e nunca é contado como aprovado. * evidence: exige que um artefato específico exista e seja válido. */ kind: 'deterministic' | 'semantic' | 'evidence'; check?: DeterministicCheck; /** Para `evidence`: id do nó cujo artefato precisa existir e ser válido. */ evidenceOf?: string; /** Critério opcional não bloqueia o veredito quando falha. */ optional?: boolean; } export interface VerificationPolicy { /** Checks aplicados diretamente ao artefato deste nó. */ deterministic: DeterministicCheck[]; /** Score semântico mínimo quando existe juiz. Sem juiz, ignorado. */ semanticMinScore?: number; /** false: critérios opcionais podem falhar sem derrubar o veredito. */ requireAllCriteria?: boolean; } export interface TaskBudget { maxTokens: number; maxTimeMs?: number; maxToolCalls?: number; /** Teto de custo em USD para esta tarefa. */ maxCostUsd?: number; } export interface OutputSchema { kind: ArtifactKind | string; /** Campos/termos que a saída deve conter (o validador de artefatos já cobre o schema do kind). */ required?: string[]; minSize?: number; } export interface TaskContract { id: string; objective: string; role: AgentRole; /** Agente sugerido (o Capability Registry pode substituir por um mais apto). */ agent?: string; skills?: string[]; /** Ids de nós cujos artefatos entram como insumo (referência, não cópia de texto). */ inputs: string[]; constraints: string[]; expectedOutput: OutputSchema; dependencies: string[]; priority: TaskPriority; budget: TaskBudget; verification: VerificationPolicy; acceptance: AcceptanceCriterion[]; /** * Tarefa dispensável quando o objetivo já está verificado (early stopping). * Crítico adversarial e revisões extras nascem opcionais. */ optional?: boolean; /** * Permissões concedidas a ESTA tarefa. Menor privilégio por construção: uma * tarefa sem `permissions` não executa tool nenhuma, e o que não está * declarado aqui é negado pela `ToolRegistry` antes de a `PolicyEngine` * sequer opinar. Não confundir com o trust tier, que é de quem PEDE. */ permissions?: ToolPermission[]; /** * Tool que esta tarefa executa (`kind: 'tool'`). Quando presente, o nó NÃO * chama modelo: roteia por `ToolRegistry`, que aplica permissão, política e * sandbox antes de executar. */ tool?: { id: string; input: unknown; }; /** * A tarefa pode pedir a própria decomposição DURANTE a execução, quando * descobrir que não cabe numa entrega só. Falso por padrão: decompor à * vontade é a colmeia que a arquitetura proíbe, com custo exponencial. * O pedido é validado, tem teto de largura e divide o orçamento do pai. */ decomposable?: boolean; } /** Erros estruturais de um contrato. Vazio = contrato utilizável. */ export declare function validateContract(contract: TaskContract): string[]; /** * Deriva um contrato mínimo de um nó de grafo já existente. Serve de ponte de * compatibilidade: grafos construídos pelos templates antigos ganham contrato * sem que o template precise ser reescrito. */ export declare function contractFromNode(node: GraphNode, opts: { objective: string; role?: AgentRole; constraints?: string[]; }): TaskContract; /** Papel default por tipo de nó: crítica/avaliação são baratas, agentes são especialistas. */ export declare function defaultRoleForNode(node: GraphNode): AgentRole; /** Anexa o contrato ao nó preservando o resto do metadata. */ export declare function attachContract(node: GraphNode, contract: TaskContract): GraphNode; /** Lê o contrato anexado a um nó (undefined em grafos pré-contrato). */ export declare function contractOf(node: GraphNode): TaskContract | undefined; //# sourceMappingURL=task-contract.d.ts.map