paqad-ai
Version:
Spec-driven development framework — AI agents that think before they type
59 lines (42 loc) • 3.25 kB
Markdown
---
name: finding-normalizer
description: Turns mixed raw evidence from docs, tests, runtime checks and advisory feeds into stable finding entries with ids, severity, effort and status, deduplicating records of the same risk. Use when raw security or audit evidence must become report-ready findings JSON, or when findings or retest statuses need normalizing, validating or stable ids.
metadata:
model_tier: medium
cacheable: 'false'
output_format: json
paqad-meta: skill.meta.yaml
---
## What It Does
Normalizes evidence from docs, tests, runtime checks, and advisory feeds into stable finding entries with consistent ids, severity, effort, and reproduction data.
Finding-id prefixes recognised by the normalizer are listed under `# code-prefix` in `assets/vocabulary.txt`:
- `PEN-*`: pentest findings (security workflow).
- `DT-*`: design-test findings (design-system audit workflow). Categories: `token | component | state | a11y | responsive | motion | copy | performance | documentation-drift`. `token` findings default to **high** severity to surface hard-coded design values (hex literals, raw px/rem, ad-hoc font stacks where a token exists).
- `SM-*`: site-map findings (site-map / site-map-retest workflow; `docs/site-map/<ts>.json`). The id is a content-addressed `SM-<hash8>`; the `SM-ADD | SM-REMOVE | SM-EDGE-STALE | SM-GUARD-DRIFT | SM-JOURNEY-BROKEN | …` names are `category` values, listed under `# site-map category` in `assets/vocabulary.txt`.
- `MD-*`: prospective module decisions. Stored under `.paqad/decisions/module-decisions/<id>.yml`; the consumer is the Attribution Gate, not the pentest workflow. Treat severity/effort/status as advisory only for `MD-*`, the binding state machine lives in `src/module-decisions/schema.ts`.
## Use This When
After raw security evidence has been collected and needs to be turned into report-ready findings or retest statuses.
## Inputs
- Read the structured evidence payload first.
- Read `references/finding-fields.md` before setting severity or effort.
- Read retest state when the workflow is `pentest-retest`.
## Procedure
1. Deduplicate findings that describe the same risk surface.
2. Pick severity, effort, and status from the closed sets in `assets/vocabulary.txt`.
3. Preserve ids and prior statuses when normalizing retest output.
4. Format the JSON exactly per `assets/output.template.json`.
5. Validate with `scripts/validate-findings.sh`: checks required fields, vocabulary, and id uniqueness.
## Output Contract
- Match `assets/output.template.json`: a JSON array of findings with `id, title, severity, effort, impact_area, evidence, reproduction, status` (plus optional `wstg_id` / `owasp_2025`).
- `severity`, `effort`, `status` must come from `assets/vocabulary.txt`.
- Output must pass `scripts/validate-findings.sh` (exit 0).
## Escalate / Stop Conditions
- Ask when two evidence records appear to describe overlapping but not identical risks.
- Warn when the available evidence is too thin to support the proposed severity.
- Do not inflate severity to compensate for missing detail.
## Resources
- `references/finding-fields.md`
- `scripts/validate-findings.sh`
- `assets/output.template.json`
- `assets/vocabulary.txt`
- `agents/openai.yaml`