teqo-backup/tests/unit/briefingSkill.unit.spec.ts
Francisco Solla 31f78f07ad
Some checks failed
Deploy / preflight (push) Has been cancelled
Deploy / verify (push) Has been cancelled
Deploy / deploy staging (teqo-staging) (push) Has been cancelled
Deploy / requeue when main advanced (push) Has been cancelled
Deploy / deploy production (teqo-1313) (push) Has been cancelled
feat(briefing): pedido dual 1313 + Lula 13 e missão do 2º turno
O briefing de capacitação passa a renderizar o pedido dual (deputado
federal 1313 e, no 2º turno, Lula 13) e a exigir ao menos uma pergunta
de 2º turno no Q&A; dossiê e boletim seguem sem CTA (prova material do
argumento, não peça de rua). Registra o changelog da entrega.
2026-10-09 04:01:20 -03:00

96 lines
4.2 KiB
TypeScript

import { existsSync, readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
// C210: the briefing skill, the command and the author subagent are prompt
// text, so the product contract (label, 4-page cap, vote literal, anchor
// fail-closed, no second research) lives in the SKILL.md prose. This guard
// fails the build if the flow, the guardrails or the CLI contract are dropped.
const repoRoot = process.cwd()
const read = (path: string): string => readFileSync(resolve(repoRoot, path), 'utf8')
const skill = read('.agents/skills/briefing-capacitacao-solla/SKILL.md')
const agent = read('.opencode/agent/briefing-capacitacao-solla.md')
const command = read('.opencode/commands/briefing-capacitacao-solla.md')
describe('skill /briefing-capacitacao-solla documents the flow', () => {
it('declares when to use it, the batch selector and the integration', () => {
expect(skill).toContain('## Quando usar')
expect(skill).toContain('## Lote (recortes)')
expect(skill).toContain('cidade:')
expect(skill).toContain('instituicao:')
expect(skill).toContain('tema:')
expect(skill).toContain('/dossie-solla-cidade')
expect(skill).toMatch(/3º entregável/)
})
it('pins the canonical builder CLI and the gitignored artifacts', () => {
expect(skill).toContain('node scripts/build-dossie-solla-briefing.mjs')
expect(skill).toContain('--unit=')
expect(skill).toContain('data/dossie-solla-')
expect(skill).toContain('docs/research/dossie-solla-')
expect(skill).toContain('gitignored')
})
it('pins the hard product literals', () => {
expect(skill).toContain('Insumo interno de capacitação — não publicar')
expect(skill).toContain('vote 1313')
expect(skill, 'the 2º-turno mission is part of the ask').toContain('Missão do 2º turno')
expect(skill, 'the pedido is dual since 08/10/2026').toContain('vote 13, Lula')
expect(skill).toMatch(/4 páginas/)
expect(skill).toContain('insumo interno')
expect(skill).toMatch(/sem CTA público/i)
})
it('pins the fail-closed content contract', () => {
expect(skill).toContain('## Contrato do')
expect(skill).toContain('factId')
expect(skill).toContain('gapReason')
expect(skill).toContain('estimatedVotes')
expect(skill).toMatch(/sem fonte, o item não entra/i)
expect(skill).toMatch(/dois lados/)
})
it('pins the hard four-page cap with declared shed and the .md superset', () => {
expect(skill).toMatch(/teto de \*\*4 páginas é rígido\*\*/)
expect(skill).toMatch(/corta por\s+prioridade/)
expect(skill).toContain('no briefing completo (.md)')
expect(skill).toMatch(/nunca\*\* são cortados/)
})
it('pins the offline guardrail: no second factual research', () => {
expect(skill).toMatch(/sem segunda pesquisa factual/i)
expect(skill).toMatch(/nunca faz segunda pesquisa factual/i)
})
})
describe('author subagent is writer-only (briefing.json)', () => {
it('stays a subagent that writes the briefing.json and returns the receipt', () => {
expect(agent).toMatch(/^---\n[\s\S]*mode: subagent[\s\S]*\n---/)
expect(agent).toContain('.briefing.json')
expect(agent).toContain('Recibo do autor')
const frontmatter = agent.match(/^---\n([\s\S]*?)\n---/)
expect(frontmatter, 'agent frontmatter must be delimited by ---').not.toBeNull()
expect(frontmatter![1]).not.toMatch(/^\s*["']?model["']?\s*:/m)
})
it('does not run the deterministic build or a new web research', () => {
expect(agent, 'author must not run the builder CLI').not.toContain('--snapshot=')
expect(agent, 'author must not do new web research').toMatch(/não\*\* faça pesquisa web/i)
expect(agent, 'author must not edit the research files').toMatch(/não\*\* edite os/)
})
})
describe('command /briefing-capacitacao-solla couples to the skill', () => {
it('references the canonical skill file and passes arguments', () => {
expect(existsSync(resolve(repoRoot, '.opencode/commands/briefing-capacitacao-solla.md'))).toBe(
true,
)
expect(command).toContain('`briefing-capacitacao-solla`')
expect(command).toContain('$ARGUMENTS')
expect(command).toContain('.agents/skills/briefing-capacitacao-solla/SKILL.md')
expect(command).toContain('insumo interno')
})
})