diff --git a/docs/onboarding-redesign-brief.md b/docs/onboarding-redesign-brief.md index 2b31e32..e512877 100644 --- a/docs/onboarding-redesign-brief.md +++ b/docs/onboarding-redesign-brief.md @@ -23,7 +23,7 @@ Virksomhetskontekst (sektor, lisens, dataklassifisering, budsjett, styringsmodel **Tilstøtende (allerede dokumentert):** `docs/devils-advocate-audit-2026-06-18.md` §167 — onboarding kan ikke representere en privat virksomhet (sektor-valg hardkodet offentlig; reguleringsliste mangler DORA/Finansforetaksloven m.m.). Bør løses i samme redesign siden det treffer samme filer. -> Merknad: `docs/onboarding-ros-analysis.md` er feildøpt — den er en Windows «clone-to-PR»-guide for ROS-featuren, **ikke** en onboarding-analyse. Vurder å døpe den om i redesignet. +> Merknad: `docs/onboarding-ros-analysis.md` var feildøpt — den er en Windows «clone-to-PR»-guide for ROS-featuren, **ikke** en onboarding-analyse. **Omdøpt i C2.4** til `docs/windows-clone-to-pr-ros-guide.md`. ## Skisserte løsningsretninger (ikke bindende — design godkjennes senere) diff --git a/docs/onboarding-redesign-plan.md b/docs/onboarding-redesign-plan.md index 0c9209c..f7655f4 100644 --- a/docs/onboarding-redesign-plan.md +++ b/docs/onboarding-redesign-plan.md @@ -102,7 +102,7 @@ C2.1 er den bærende delsesjonen (etablerer lagring + resolver alle andre bygger - **Ikke** del av KB-mekanisme-redesignet (`kb-mechanism-redesign-plan.md`) eller Spor B (`skill-lifecycle-spor-b-plan.md`). Eget spor, egen plan. - C3 (kurs/training, #25) tas **etter** C2. -- `docs/onboarding-ros-analysis.md` er feildøpt (Windows clone-to-PR-guide, ikke onboarding-analyse) — vurder omdøping i C2.4 (lav prioritet). +- `docs/onboarding-ros-analysis.md` var feildøpt (Windows clone-to-PR-guide, ikke onboarding-analyse) — **omdøpt i C2.4** til `docs/windows-clone-to-pr-ros-guide.md`. --- @@ -159,3 +159,16 @@ C2.1 er den bærende delsesjonen (etablerer lagring + resolver alle andre bygger - **Kjent begrensning (pre-eksisterende, ikke C2.3-introdusert):** CLI-kallet i `onboard.md` bruker relativ `node scripts/...`-sti (antar cwd = plugin-rot), identisk konvensjon som `kb-update.md`. Org-/config-stiene er home-baserte (robuste). - **Verifisert:** detection-schedule 33/33 (+10: serialize round-trip + writeScheduleConfig merge/backup/end-to-end) · backup-restore 15/15 (+3: `backupFile`) · kb-update 213 · kb-eval 100 · validate PASSED (239/0/0) · test-hooks 11/11 · kb-integrity 192/192 (220 baseline-warns) · discovery 13/13 · gitleaks 3 PRE-EKSISTERENDE (`playground/vendor/`). - **Neste:** C2.4 (verifiser privat-sektor-paritet #4 + lukk evt. §167-residu). + +### C2.4 — RESULTAT (verifikasjon + regresjonsvakt, TDD rød→grønn) + +**Mål nådd:** **K4 verifisert oppfylt** og låst mot regresjon → privat-sektor-paritet i onboarding er bevist, ikke antatt. + +- **Funn (kildehistorikk):** privat-greinen ble innført i commit **`6e1fc6d`** («#7d privat-sektor-paritet … onboarding-forgrening … audit §5»), FØR C2.1–C2.3. §167-onboarding-residuet (audit §5 punkt #1) var altså **allerede lukket i kode**. C2.4 var dermed ekte **verifikasjon**, ikke nybygg — som planraden forutså. +- **K4 bekreftet mot kilden** (`agents/onboarding-agent.md` Phase 1): sektortype forgrener offentlig/privat; privat sektor-grein lister Finans/bank/forsikring, Industri/produksjon, Handel, Energi, Telekom (**bank slipper «Annet»**); privat reg-sett har DORA, Finansforetaksloven, Finanstilsynets IKT-forskrift, Verdipapirhandelloven, Hvitvaskingsloven; private spørres ALDRI Offentleglova/Arkivloven/Forvaltningsloven. Orkestratoren (`commands/onboard.md`) er sektor-nøytral (delegerer intervjuet). +- **Ny regresjonsvakt:** `tests/test-onboarding-parity.sh` (14 asserts mot kilden, ikke fixture — onboarding er interaktivt `AskUserQuestion`, ingen output-fixture). Bruker `lib/e2e-helpers.sh`-mønsteret som de andre output-testene. Wiret inn i `tests/run-e2e.sh` (`--onboarding`, med i `--all`). **TDD-diskriminering bevist:** testen kjørt mot en strippet offentlig-only-kopi → 13/14 FAIL (rød); mot ekte fil → 14/14 PASS (grønn). +- **§167-residu (d) bevisst IKKE bygget (begrunnet):** anbefalingens «betinget Fase 3-gren med egen dataklassifiserings-taksonomi for regulert privat sektor» er gull-plating UTENFOR K4. Dagens Fase 3-taksonomi (Åpen/Intern/Fortrolig/Strengt fortrolig) er en alminnelig norsk *bedrifts*-klassifisering — en privat virksomhet fullfører Fase 3 uten hindring; kun «Hemmelig (sikkerhetsloven)» er offentlig-spesifikk og velges simpelthen ikke. K4 krever ikke egen taksonomi. Ingen knott uten påvist behov (speiler C2.2-/C2.3-disiplinen). +- **Medrydd (plan §Avgrensning):** feildøpte `docs/onboarding-ros-analysis.md` (en Windows clone-to-PR-bidragsyterguide, ikke onboarding-analyse) **omdøpt** → `docs/windows-clone-to-pr-ros-guide.md` (`git mv`); plan- + brief-referanser oppdatert. Fjerner reell forvekslingsfelle (utvikler- vs. virksomhets-onboarding). +- **Avgrensning (bekreftet):** audit §5 punktene #2–#6 (sektor-parametrisering i classify/dpia/ros/frimpact/utredning/review, README/help/playground privat-bane) er IKKE C2.4-scope. Mange ble adressert i `6e1fc6d`; gjenstående er eget arbeid utenfor C2 (onboarding-paritet). Ikke eskalert uten godkjenning. +- **Verifisert:** onboarding-parity 14/14 (NY) · validate PASSED (239/0/0) · e2e alle suiter grønne · discovery 13/13 · test-hooks 11/11 · kb-integrity 192/192 (220 baseline-warns) · gitleaks 3 PRE-EKSISTERENDE (`playground/vendor/`). +- **C2 KOMPLETT** (C2.1→C2.4 ✅). **Neste:** C3 (kurs/training, #25) — eller release-beslutning (v1.16.0) i push-vindu. diff --git a/docs/onboarding-ros-analysis.md b/docs/windows-clone-to-pr-ros-guide.md similarity index 100% rename from docs/onboarding-ros-analysis.md rename to docs/windows-clone-to-pr-ros-guide.md diff --git a/tests/run-e2e.sh b/tests/run-e2e.sh index b6806f5..8a4acc8 100755 --- a/tests/run-e2e.sh +++ b/tests/run-e2e.sh @@ -1,6 +1,6 @@ #!/bin/bash # run-e2e.sh — Run E2E regression tests for agent outputs -# Usage: bash tests/run-e2e.sh [--security] [--cost] [--summary] [--ros] [--ai-act] [--playground] [--kb-update] [--all] +# Usage: bash tests/run-e2e.sh [--security] [--cost] [--summary] [--ros] [--ai-act] [--playground] [--kb-update] [--onboarding] [--all] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -18,6 +18,7 @@ RUN_ROS=false RUN_AI_ACT=false RUN_PLAYGROUND=false RUN_KB_UPDATE=false +RUN_ONBOARDING=false if [ $# -eq 0 ] || [ "${1:-}" = "--all" ]; then RUN_SECURITY=true @@ -27,6 +28,7 @@ if [ $# -eq 0 ] || [ "${1:-}" = "--all" ]; then RUN_AI_ACT=true RUN_PLAYGROUND=true RUN_KB_UPDATE=true + RUN_ONBOARDING=true else while [ $# -gt 0 ]; do case "$1" in @@ -37,8 +39,9 @@ else --ai-act) RUN_AI_ACT=true ;; --playground) RUN_PLAYGROUND=true ;; --kb-update) RUN_KB_UPDATE=true ;; + --onboarding) RUN_ONBOARDING=true ;; *) - echo "Usage: bash tests/run-e2e.sh [--security] [--cost] [--summary] [--ros] [--ai-act] [--playground] [--kb-update] [--all]" + echo "Usage: bash tests/run-e2e.sh [--security] [--cost] [--summary] [--ros] [--ai-act] [--playground] [--kb-update] [--onboarding] [--all]" exit 1 ;; esac @@ -73,6 +76,10 @@ if $RUN_AI_ACT; then bash "$SCRIPT_DIR/test-ai-act-output.sh" || FAILURES=$((FAILURES + 1)) fi +if $RUN_ONBOARDING; then + bash "$SCRIPT_DIR/test-onboarding-parity.sh" || FAILURES=$((FAILURES + 1)) +fi + if $RUN_PLAYGROUND; then bash "$SCRIPT_DIR/test-playground-v3.sh" || FAILURES=$((FAILURES + 1)) bash "$SCRIPT_DIR/test-playground-parsers.sh" || FAILURES=$((FAILURES + 1)) diff --git a/tests/test-onboarding-parity.sh b/tests/test-onboarding-parity.sh new file mode 100755 index 0000000..8d1e990 --- /dev/null +++ b/tests/test-onboarding-parity.sh @@ -0,0 +1,64 @@ +#!/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 Privat-sektor-paritet (K4)" + +# === 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" + +# === 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