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>
108 lines
5.5 KiB
Bash
Executable file
108 lines
5.5 KiB
Bash
Executable file
#!/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 1–5 (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
|