ms-ai-architect/tests/test-onboarding-parity.sh
Kjell Tore Guttormsen 59b4de938f feat(ms-ai-architect): Spor E E-polish — per-kategori typisk/sjelden-hint i onboarding Phase 1–5 (TDD) [skip-docs]
Speiler Phase 6-coachingen til de fem strukturerte fasene: hver Phase 1–5
får et `**Hint — typisk relevant / sjelden relevant:**`-prosahint som agenten
deler med brukeren før AskUserQuestion-spørsmålene, slik at intervjuet coacher
mot riktig alternativ i stedet for å fyres av blankt. Hintene er grunnet i
filens egne option-lister (ingen nye eksterne påstander → verifiseringsplikt
ivaretatt). Agent-fil, ikke skill → ingen judge-/score-effekt.

TDD: 4 nye assert i test-onboarding-parity.sh (RED→GREEN) — ASCII-only anker
«typisk relevant / sjelden relevant» ×5 + «Del med brukeren» + begge framing-ord.
Bash 3.2-fix: ankeret holdes ASCII-only fordi multibyte em-dash i en shell-var
under `set -u` + gåseøyne-interpolasjon kræsjer scriptet.

e2e onboarding-parity 25/25, validate 0/0, discovery 13/13, kb-integrity 192/0,
full e2e grønn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 20:00:07 +02:00

108 lines
5.5 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# test-onboarding-parity.sh — K4 (privat-sektor-paritet) regresjonsvakt for onboarding.
#
# Låser audit §5 punkt #1 (devils-advocate-audit-2026-06-18.md:167): en privat
# virksomhet skal kunne fullføre onboarding UTEN å velge «Annet» på sektor, med en
# relevant (privat) reguleringsliste, og uten å bli spurt rene offentlig-sektor-lover.
#
# Onboarding-intervjuet er interaktivt (AskUserQuestion) → ingen fixture-fangst som de
# andre output-testene. Vi asserterer derfor mot KILDEN (agents/onboarding-agent.md +
# commands/onboard.md): forgreningen og de private alternativene må være til stede.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/lib/e2e-helpers.sh"
PLUGIN_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Tillat override (rød-fase-diskrimineringsbevis kjører testen mot en strippet kopi).
AGENT="${ONBOARDING_AGENT_FILE:-$PLUGIN_ROOT/agents/onboarding-agent.md}"
ORCH="${ONBOARDING_ORCH_FILE:-$PLUGIN_ROOT/commands/onboard.md}"
if [ ! -f "$AGENT" ]; then
echo "ERROR: Onboarding agent not found: $AGENT"
exit 1
fi
init_suite "Onboarding-agent kildesjekk (K4-paritet + Phase 6 guided-prose)"
# === Forgrening: sektortype velges først og styrer oppfølgingen ===
assert_matches_pattern "$AGENT" "Sektortype.*Offentlig sektor, Privat sektor" \
"Sektortype forgrener offentlig/privat på toppnivå"
assert_matches_pattern "$AGENT" "forgren intervjuet" \
"Eksplisitt instruks om å forgrene intervjuet på sektortype"
# === K4 kjerne: privat virksomhet trenger IKKE velge «Annet» på sektor ===
# Den private sektor-greinen må liste navngitte private sektorer.
assert_matches_pattern "$AGENT" "Hvis Privat sektor.*Finans/bank/forsikring" \
"Privat sektor-grein lister Finans/bank/forsikring (bank slipper «Annet»)"
for sektor in "Industri/produksjon" "Handel" "Energi" "Telekom"; do
assert_matches_pattern "$AGENT" "Hvis Privat sektor.*${sektor}" \
"Privat sektor-grein lister ${sektor}"
done
# === K4 kjerne: relevant privat reguleringsliste ===
for reg in "DORA" "Finansforetaksloven" "Finanstilsynets IKT-forskrift" \
"Verdipapirhandelloven" "Hvitvaskingsloven"; do
assert_matches_pattern "$AGENT" "$reg" \
"Privat reg-sett inneholder ${reg}"
done
# === Forgrening verner private mot rene offentlig-sektor-lover ===
assert_matches_pattern "$AGENT" "ALDRI private virksomheter om Offentleglova" \
"Private spørres ALDRI Offentleglova/Arkivloven/Forvaltningsloven"
# === Spor E krav 2: Phase 6 guided-prose (coaching) ===
# Operatør-direktiv S39 (memory: onboarding-quality-bar): fri-kontekst-fasen skal
# ikke bare stille ÉtT blankt spørsmål — den skal COACHE brukeren på hva som typisk
# hører hjemme og hva som trygt kan hoppes over, så fri-konteksten faktisk gjør
# rådene mer treffsikre (multiplikator-effekten). Vi asserterer mot agent-kilden.
assert_matches_pattern "$AGENT" "coache? brukeren" \
"Phase 6 instruerer agenten om å coache brukeren (ikke bare stille blankt spørsmål)"
assert_matches_pattern "$AGENT" "[Pp]resenter de to listene" \
"Phase 6 ber agenten presentere coaching-listene for brukeren"
assert_matches_pattern "$AGENT" "typisk hører hjemme" \
"Phase 6 lister hva som typisk bør med (inkluderings-coaching)"
assert_matches_pattern "$AGENT" "vanligvis kan hoppe over" \
"Phase 6 lister hva som vanligvis kan hoppes over (ekskluderings-coaching)"
assert_matches_pattern "$AGENT" "allerede.*fanget i de fem strukturerte kategori" \
"Phase 6 ber bruker ikke gjenta det de fem strukturerte kategoriene alt fanget"
assert_matches_pattern "$AGENT" "(secrets|sensitive personopplysninger).*ALDRI" \
"Phase 6 advarer mot å lime inn secrets/sensitive personopplysninger"
# Regresjon: fri-konteksten lagres fortsatt ordrett (ikke omskrevet/forkortet)
assert_matches_pattern "$AGENT" "ordrett" \
"Phase 6 lagrer fortsatt brukerens prosa ordrett (regresjonsvakt)"
# === Spor E (E-polish): per-kategori prosa-hint Phase 15 (speilet på Phase 6-coachingen) ===
# De fem strukturerte fasene bruker AskUserQuestion, men skal IKKE fyres av blankt: hver fase
# skal gi et kort «typisk relevant / sjelden relevant»-hint slik at agenten coacher brukeren mot
# riktig alternativ — samme multiplikator-tanke som Phase 6, komprimert til strukturerte valg.
# ASCII-only anker (ingen em-dash/gåseøyne i shell-var → bash 3.2 + set -u-trygt).
HINT_ANCHOR='typisk relevant / sjelden relevant'
hint_count=$(grep -cF "$HINT_ANCHOR" "$AGENT" || true)
if [ "${hint_count:-0}" -ge 5 ]; then
pass "Alle 5 strukturerte faser har et per-kategori typisk/sjelden-hint ($hint_count funnet)"
else
fail "Per-kategori hint mangler — fant kun ${hint_count:-0}/5 hint-ankere"
fi
# Agenten skal faktisk DELE hintet med brukeren (speiler Phase 6 «Presenter de to listene ... FØR»)
assert_matches_pattern "$AGENT" "Del med brukeren" \
"Per-kategori hint instrueres delt med brukeren før spørsmålene"
# Begge framing-ordene finnes (inkludering + ekskludering, som Phase 6s to lister)
assert_matches_pattern "$AGENT" "typisk relevant" \
"Hint-framing inneholder «typisk relevant» (inkludering)"
assert_matches_pattern "$AGENT" "[Ss]jelden relevant" \
"Hint-framing inneholder «sjelden relevant» (ekskludering)"
# === Orkestratoren er sektor-nøytral (delegerer, hardkoder ikke offentlig) ===
if [ -f "$ORCH" ]; then
if grep -qE "Onboarding-agenten styrer selve intervjuet" "$ORCH"; then
pass "Orkestrator delegerer intervjuet til agenten (sektor-nøytral)"
else
warn "Orkestrator: fant ikke delegerings-note (sjekk onboard.md)"
fi
fi
print_summary