Commit graph

106 commits

Author SHA1 Message Date
dc0b627e98 feat(ms-ai-architect): C2.1 lib/user-data resolver + ambient org-injeksjon + C1 config bakoverkompat (TDD) [skip-docs]
Bæreren i C2 onboarding-redesign (#26). TDD: test FØR kode.

- lib/user-data.mjs (NY, ren, SKRIVER ALDRI; kun node:os/path):
  resolveUserDataDir/resolveOrgDir/resolveConfigPath peker ~/.claude/ms-ai-architect/
  (uavhengig av pluginRoot -> overlever reinstall, K2). CONFIG_FILENAME delt med C1
  (en sannhetskilde). buildOrgSummary: deterministisk, lengde-kappet H2-ekstraksjon.
- detection-schedule.mjs: loadScheduleConfig(pluginRoot, home=homedir()) leser
  bruker-sti FORST, fallback plugin-rot. Lokal CONFIG_FILENAME -> importeres fra resolver.
  Alle 3 kallere bruker ett-arg-kall (uendret oppforsel).
- session-start-context.mjs: injiserer buildOrgSummary ambient (K1) som egen
  Virksomhetskontekst-blokk; status-nudge beholdt nar org tom.

Verifisert: user-data 16/16 · detection-schedule 23/23 · test-hooks 10/10 ·
kb-update 191 · kb-eval 100 · validate PASSED.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:34:05 +02:00
071601bb9e feat(ms-ai-architect): Sesjon 24 — C1 Tier 2 lokal launchd-scheduler (deteksjon-only, ToS-trygt) [skip-docs]
Tier 1 (SessionStart-hook) kjører deteksjon kun når en Claude-sesjon starter.
Tier 2 installerer en lokal launchd LaunchAgent som fyrer SAMME Claude-frie
entrypoint daglig (kl. 03:00), uavhengig av sesjoner = ekte bakgrunn mellom
sesjoner. ToS-trygt: entrypointet kan strukturelt ikke invokere claude.

Søk-først-verifisert (2026-06): launchd > cron (Apple-anbefalt; cron krever
Full Disk Access); StartCalendarInterval fanger opp etter dvale; launchd har
minimalt PATH + ekspanderer ikke ~; process.execPath = Cellar-sti som dør ved
`brew upgrade node` → plistens PATH inkluderer /usr/local/bin.

Levert (TDD, test FØR kode):
- lib/launchd-plist.mjs (REN, SKRIVER ALDRI): renderPlist (XML-escape,
  StartCalendarInterval, PATH-fix), defaultLabel, resolvePaths.
- scheduler.mjs (TYNN CLI): install|uninstall|status|run-now|print|run.
  Strukturelt Claude-fri (kun process.execPath på run-detection.mjs +
  launchctl; kilde-grep-testet). run gater på os_scheduler_cadence →
  delegerer til run-detection.mjs. uid-0-nekt; idempotent bootout.
- detection-schedule.mjs (additiv, Tier-1 urørt): os_scheduler_cadence
  ('daily' default | 'interval') + daysSinceLastPoll ren helper.
- commands/kb-update.md: Tier-1/Tier-2-doc + caveats (uninstall=pause;
  re-install etter node-upgrade).

Operatør-valg: daglig default, kadens egen innstilling (settes i onboarding/C2).

Verifisert: launchd-plist 13/13 · detection-schedule 21/21 · kb-update 173 ·
kb-eval 100 · validate 239/0 · test-hooks 6/6 · plutil -lint OK · live
install→status→idempotent→uninstall på maskinen (gui/501, rent).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:59:18 +02:00
f8a160585f test(ms-ai-architect): Sesjon 23 — auto_discover stale-felt assertion korrigert (søk-verifisert, 13/13) [skip-docs]
Oppgave 0 (#44): søk-først (claude-code-guide mot offisiell docs) verifiserte at
`auto_discover` IKKE er et gyldig Claude Code plugin.json-felt — auto-discovery er
implisitt default (code.claude.com/docs/en/plugins-reference; ukjent felt gir kun
valideringsadvarsel, ikke feil). → stale konvensjon, IKKE manglende felt.

- tests/test-plugin-discovery.sh: stale hard-assertion (krevde `auto_discover: true`)
  → optional-felt-logikk som speiler validate-plugin.sh (fravær = PASS «auto-discovery
  implisitt»; present må være true). plugin.json URØRT (la IKKE til ugyldig felt).
  12/13 → 13/13.

validate 239/0 (ingen regresjon). STATE oppdatert: NESTE = C1 Tier 2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 13:48:40 +02:00
039b61ca24 chore(ms-ai-architect): Sesjon 22 — rydd stale pre-edit-secrets-testreferanser [skip-docs]
pre-edit-secrets.mjs-hooken ble bevisst fjernet i v1.7.0 (secrets scanning
consolidated to llm-security, CHANGELOG l.413), men 2 testfiler refererte den
fortsatt og ga falske feil.

- tests/test-hooks.sh: fjernet pre-edit-secrets-testblokk (5 tester) → 6/6 grønn.
- tests/test-plugin-discovery.sh: fjernet pre-edit-secrets fra CLAUDE.md-dok-loop.

Separat funn (IKKE fikset, scope-guard): test-plugin-discovery.sh har 1
gjenværende feil `auto_discover is not true` — plugin.json mangler feltet; ikke
hook-relatert, krever søk-først (gjeldende felt vs stale test). Flagget → task #44.

De 4 sporede suitene uendret (validate 239 · kb-update 155 · kb-eval 100 · kb-integrity 192/192).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 23:08:11 +02:00
150b20584e feat(ms-ai-architect): Sesjon 21 — C1 Tier 1 opt-in session-forankret deteksjon (ToS-forankret) [skip-docs]
Spor C fase C1 Tier 1. Ny verifisert ToS-analyse avdekket falsk «enten/eller»:
Consumer Terms §3.7 begrenser automatisert tilgang til Claude/Anthropic, IKKE
kjøring av lokale node-scripts. Deteksjon kontakter aldri Claude → utenfor
ToS-flaten; apply (eneste Claude-steg) forblir manuelt/in-session/gated.

- lib/detection-schedule.mjs (ren): opt-in config (default AV) + shouldRunDetection
  gate + DETECTION_STEPS allow-liste + summarizeSkillLifecycle. Zero-dep parser.
- run-detection.mjs: Claude-FRITT entrypoint — kjører kun `node` på de
  allow-listede deteksjons-scriptene; kan ikke invokere claude (guard-testet).
- session-start-context.mjs: ubetinget bakgrunns-spawn → opt-in (default AV
  spawner ingenting) + surfacer skill-signaler read-only.
- commands/kb-update.md: opt-in-seksjon + ToS-note; ms-ai-architect.local.md.example.

TDD: ny test-detection-schedule.test.mjs (16). kb-update 139→155.
Suiter uendret: validate 239 · kb-eval 100 · kb-integrity 192/192.
0 skills/-mutasjon. Tier 2 (lokal OS-timer, deteksjon-only) = neste økt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 22:54:18 +02:00
e47fc9bd59 feat(ms-ai-architect): Sesjon 20 — B3 create_skill (dvelende, konstruktiv op) [skip-docs]
B3 + Spor B (krav 5+6) KOMPLETT. create_skill er speilbildet av de
destruktive ops: merge/saner/retire beviser "ingen kuratert verdi TAPT";
create beviser "ingen sub-bar skill FØDT" (kvalitetsgulv). Ingen ny
domene-skill shippet (svar 3) — mekanismen bevist, ikke brukt.

- planCreateSkill (ren): genererer scaffold + selv-validerer mot eval.mjs
  sine EGNE checkers (K2/K3/K5/K6/refTall + K10) — rubrikken har én kilde.
  Guardrail ok iff alle deterministiske K passerer + K10<terskel + navn ledig.
- TEST_DOMAIN_SPEC: kanonisk dvelende-scaffold (born compliant, K5 ratio 1.0).
- runCreatePlan (uren): gated dry-run, 0 skriving til skills/.
- applyApprovedAction create-gren: re-plan fersk → revalider (drift+kollisjon)
  → skriv scaffold + persister taksonomi-tillegg → flipp ledger.
- applyCategoryAdditions (taxonomy.mjs): additiv, klobrer aldri eksisterende eier.
- CLI create-verb i plan-skill-op + apply-skill-op.

TDD: ny test-skill-ops-create.test.mjs (16). kb-eval 84→100.
Suiter uendret: validate 239 · kb-update 139 · kb-integrity 192/192.
Deterministisk eval K1–K10 for de 5 ekte: 0 regresjon. 0 ekte skills/-mutasjon.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 21:37:19 +02:00
de3a9a483b feat(ms-ai-architect): Sesjon 19 — B3 merge-apply (cross-skill + taksonomi-persist) [skip-docs]
Merge-apply = den tyngste destruktive op-en: eksekver en operatør-godkjent
merge_skills-entry → faktisk cross-skill skills/-mutasjon. Tre mekanismer
som sanitize/retire ikke trengte: kuratert relokasjon (ikke arkiv),
taksonomi-persistering, retire-av-absorbert.

- taxonomy.mjs (ny persist): saveTaxonomy (atomisk .tmp+rename, speiler
  saveDecisions) + ren applyCategoryReassignments (repointer KUN der eier
  === from; absent/allerede-flyttet = no-op). Lag-0 er normalt read-only;
  ENESTE writer = gated merge-apply.
- applyApprovedAction merge-gren (skill-ops.mjs): re-plan fersk → revalidér
  (kollisjon → guardrail.ok=false → abort) → flytt absorbed-refs → absorber
  (moveFile; flyttingen ER bevaringen set-equality beviser) → persister
  taksonomi-repoint fra FERSK plan (drift-sikker) → arkivér absorbed-SKILL.md
  FØR rmdir → flipp ledger approved→applied. Description-forsoning forblir
  MANUELL (planner-kontrakt: apply rører aldri absorber-SKILL.md).
  archiveMove→moveFile (generisk: arkiv + kuratert flytt).
- CLI apply-skill-op.mjs merge <absorber> <absorbed> — lookup via actionKey
  (merge_skills:<sortert par>); default PREVIEW, --apply = dobbel-gate.

TDD, tmpdir-fixtures: 0 ekte skills/-mutasjon. Ny test-skill-ops-merge-apply
(7) + 2 taksonomi-tester; fjernet foreldet merge-throws fra S18-fila. Tester:
kb-eval 78→84, kb-update 137→139; validate 239 · kb-integrity 192/192 uendret.
eval --json deterministisk uendret (K10 eng+infra FAIL, øvrige PASS).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:54:13 +02:00
4ac18a76c8 feat(ms-ai-architect): Sesjon 18 — B3 apply-path (sanitize+retire), merge→S19 [skip-docs]
Apply-path = den destruktive frontieren: eksekver en operatør-godkjent
(status:approved) ledger-entry → faktisk skills/-mutasjon. Staget per
operatør-beslutning til single-skill ops (sanitize+retire); merge-apply
isoleres til S19 (krever taksonomi-persistering + cross-skill flytt).

- revalidateApply (ren, skill-ops.mjs): idempotent revalidering mot fersk
  re-plan — nekter ved status≠approved, op-mismatch, fersk guardrail≠ok,
  eller drift (isDeepStrictEqual fresh vs approved guardrail-snapshot).
- applyApprovedAction (impur): arkiver-så-slett (rename skills/…→archive/…
  atomisk; retire rmdir'er tom katalog sist) + flipp ledger approved→applied.
  apply:false = preview (0 mutasjon). merge_skills → throw (S19).
- setActionStatus (ren, decisions-io.mjs): ledger status-transisjon, bevarer
  targets+guardrail, audit-record beholdes.
- CLI apply-skill-op.mjs {list|sanitize|retire} — default PREVIEW, --apply =
  dobbel-gate utover ledger-approved.

TDD, tmpdir-fixtures: 0 ekte skills/-mutasjon. Tester: kb-eval 66→78,
kb-update 132→137; validate 239 · kb-integrity 192/192 uendret.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:32:51 +02:00
f7b622b318 feat(ms-ai-architect): Sesjon 17 — B3 sanitize_skill + retire_skill dry-run-planners [skip-docs]
Speiler S16 merge-mønsteret: rene planners (leser ingen disk, anvender
ingenting) + impurt skall med gated --write. 0 skriving til skills/.
Intern kb-eval maintenance-tooling — ingen brukervendt /architect-kommando.

- planSanitizeSkill: fjerner KUN dødt innhold (kb-integrity orphan/dead-path).
  Guardrail refuserer fjerning av kuratert/manglende innhold (illegalRemovals/
  missingRemovals MÅ være tom). Dateless = kuratert, behandles ikke her.
- planRetireSkill: hel-skill m/ obligatorisk arkivering; guardrail refuserer
  hard delete (--hard -> archiveDir=null, ok=false). taxonomyOrphaned flagget.
- loadSkillOrphans (read-only) + runSanitizePlan/runRetirePlan (gated).
- CLI plan-skill-op.mjs utvidet: {sanitize|retire} <skill> [--hard].

Ekte dry-runs: sanitize ms-ai-security 62/33 orphans OK · retire
ms-ai-infrastructure 35 arkivert OK · --hard FAILED (blokkert). git clean.

TDD: test-skill-ops-sanitize-retire.test.mjs (16). kb-eval 50->66.
Baseline uendret: validate 239 · kb-update 132 · kb-integrity 192/192.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 17:45:37 +02:00
f03a0e08b2 feat(ms-ai-architect): Sesjon 16 — B3 ledger action-lag + merge_skills dry-run-planner
Spor B / B3 start. Operatør-gated dry-run for skill-livssyklus, merge først.

- decisions-io.mjs: additivt skill-nøklet `actions`-lag ved siden av urørt
  URL-nøklet `decisions` (14 URL-tester urørt = regresjonsbevis). version=1,
  loadDecisions backfiller manglende actions-nøkkel. Nye rene fn: actionKey
  (merge symmetrisk på paret), isActionDecided, recordAction (no-mutate),
  listActions. Policy A gjelder også actions.
- scripts/kb-eval/lib/skill-ops.mjs: ren planMergeSkills → {entry,diff,guardrail},
  leser ingen disk, anvender INGENTING. Guardrail = ingen kuratert verdi tapt
  (count-invariant + set-equality + kollisjons-deteksjon; ok=false ved klobring).
  Impur skall loadSkillRefs/runMergePlan + CLI plan-skill-op.mjs (gated --write).
- Ekte eng↔infra dry-run: guardrail OK (34+153=187, 0 kollisjoner), 153 fil-flytt
  + 7 taksonomi-reassign + retire eng; 0 skriving til skills/, ledger uendret
  (retning er operatør/judge-valg, ikke pushet gjennom gaten).
- TDD: test-decisions-actions (10) + test-skill-ops-merge (10, inkl. byte-for-byte
  skills/-snapshot som no-write-bevis). kb-eval 40→50, kb-update 122→132.
  Regresjon grønn: validate 239, kb-integrity 192/192.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 17:10:33 +02:00
ba597eb988 feat(ms-ai-architect): Sesjon 15 — B2 K10 søsken-scope-ikke-overlapp
- Refaktor: overlap-kjerne flyttet til scripts/kb-eval/lib/sibling-overlap.mjs
  (bryter sirkulær import eval.mjs<->detect); detect re-eksporterer → B1-tester urørt
- K10 = søsken-scope-ikke-overlapp, deterministisk cross-skill: perSkillSiblingOverlap
  + attachSiblingOverlap i eval.mjs. combined = boundaryTension + df-vektet leksikalsk;
  per-skill verdikt = verste søskenpar; terskel 7.0 (naturlig gap 7.42→6.67)
- Empirisk (alle 5): eng+infra FAIL (7.42 mot hverandre), advisor/gov/sec PASS
  → eng↔infra-signal mater B3 merge/saner (ikke blokkering)
- Gated baseline-regen via --write (descriptions urørt → judge K1/K4/K7/K8/K9 merget
  uendret, ikke fabrikkert); rubric K1-K10
- TDD: +9 tester (tests/kb-eval/test-k10-sibling-overlap.test.mjs), kb-eval 31→40
- 0 skriving til skills/. Suiter: validate 239 · kb-update 122 · kb-integrity 192/192
2026-06-20 11:59:59 +02:00
5ad4ed025c feat(ms-ai-architect): Sesjon 14 — B1 fullført (coverage/gap + bloat/stale) [skip-docs]
Utvider scripts/kb-eval/detect-skill-lifecycle.mjs med to deterministiske
detektorer (B1 nå komplett, 3 seksjoner i skill-lifecycle-report.json).
Skriver ALDRI til skills/ — kun rapport; kandidater mater decisions.json + gate (B3).
Intern kb-eval-tooling: ingen brukervendt kommando/agent/skill/hook endret.

Detektor 2 — coverage/gap (innen-domene): taksonomi category_skill (deklarert
eierskap) vs fysisk disk-mappetelling. Klasser gap/thin/orphan/misowned.
Empirisk: 21 deklarerte kat, 20 dekket, 1 gap (security-scoring — deklarert
men ingen disk-mappe; innhold bor i ai-security-engineering = fantom-rutekat),
2 tynne (development=1, platforms=5).

Detektor 3 — bloat/stale (per skill): K3-margin (eval.checkK3 body vs 500) +
dateless ref-andel (mangler Last updated:-header = uverifiserbar ferskhet).
Disk-only/deterministisk; poll-avledet staleness (change-report) bevisst utenfor.
Empirisk: 0 split-kandidater, 1 saner (ms-ai-governance 4/78 dateless).

TDD: 8 nye tester (coverage 4, stale-primitiv 1, bloat 3). kb-eval 23->31.
Gate: validate 239, kb-update 122, kb-eval 31, kb-integrity 192/192 — grønn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-20 11:34:57 +02:00
2665a3a2d8 feat(ms-ai-architect): Sesjon 13 — B1 overlap-detektor (skill-livssyklus)
Spor B fase B1, første detektor (lag-1-analog på SKILL-granularitet).
PRODUSERER KUN RAPPORT — skriver aldri til skills/ (invariant bekreftet).

Detektor (scripts/kb-eval/detect-skill-lifecycle.mjs) kombinerer to
deterministiske overlapp-signaler per skill-par:
- grensetension: operatør-kuratert k1-trigger-prompts.json belongs_to-graf
  (out_of_domain = håndmerkede confusable-naboer), symmetrisk telt
- df-vektet leksikalsk trigger-surface-overlapp (1/df nedvekter domene-
  vanlige ord som «azure»; format-boilerplate «triggers» filtrert)
combined = grensetension + weightedScore.

Empirisk: eng↔infra topper (combined 7.42, tension 6, delt: architecture/
azure/data/multi) — operatørens Azure-deployment-grenseinstinkt bekreftet.
Surfaces som focusPair (operatør-utpekt B1-mål).

CLI: default human-summary · --json · --write (rapport gitignored som de
andre deteksjonsrapportene; detektor + kuraterte inputs er tracked).

TDD: 8 nye tester i tests/kb-eval/ (tokenize, surface, df, lexical, pairKey,
tension differensial-sjekk, full compute m/determinisme). Gate møtt.
Ingen regresjon: validate 239 · kb-update 122 · kb-eval 23 (15+8) · kb-integrity 192/192.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-20 11:17:19 +02:00
e42a84fb7b feat(ms-ai-architect): Sesjon 6 - lag 3 verifisering-INN (authority-binding)
Lag 3 etablerer per-fil autoritetsbinding som mater verify-out regel 3 (autoritets-mismatch — regresjonens rotårsak, inert til nå pga 0% dekning). Designvalg (operatør 2026-06-19): HEADER-AS-TRUTH — en fils **Source:**-header ER den utpekte autoriteten. Gjetter ALDRI fra siterte URLer (251/303 filer siterer 4-10 → gjetning ville fått regel 3 til å bomme + 303 operatør-beslutninger = primær-fallgruven).

- lib/authority.mjs (ren lib, SKRIVER ALDRI; kun read-only kb-headers+url-normalize): resolveAuthority (validert http(s); fri tekst avvist; ikke-MS-autoritet som EU-forordning tillatt), collectDeclaredSources (normalisert Set), markUrlAuthority, authorityCoverage. - build-registry: recomputer authority_source per URL-entry fra headere (ikke carry-over) + dekningslogg. - commands/kb-update.md §4 c1: authority_source=resolveAuthority(fil) → lag-5 c2.

TDD: 11 tester FØR kode inkl. import-invariant + ende-til-ende regel 3 (source_url ≠ header-autoritet → flagged). Tester: validate 239 · kb-update 122 (+11) · kb-eval 15 · kb-integrity 115/115.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 22:58:10 +02:00
48884b67a6 feat(ms-ai-architect): Sesjon 5 - transformasjonslag (lag 4, doc→KB-fil)
Lag 4 destillerer et hentet Microsoft Learn-dokument til en KB-referansefil. Speiler mønsteret fra decisions-io/verify-out: ren-funksjon-lib + tynn LLM-integrasjon + TDD. lib/transform.mjs SKRIVER ALDRI — returnerer content/verdict/sti; skriving skjer kun via operatør-gate etter lag 5.

Nøkkelfunn/-fiks: gammel prompt-template.md la kilder i en bunn-seksjon, men build-registry/kb-headers.parseSourceHeader skanner kun øverste 500 bytes → authority_source-dekning = 0 %. Lag 4 legger **Source:** i HEADER-blokka — forutsetningen for at lag 3 (fremtidig) kan backfille authority_source og lag-5 regel 3 fyrer.

- buildKbHeader({title,status,category,source,lastUpdated}): Status+Source obligatoriske (kaster ved mangel). - validateKbFile(content) → {valid,missing[]}; bruker parseSourceHeader (én sannhetskilde med build-registry). - buildChange(...): eksplisitt lag-4→lag-5-bro, mater classifyChange. - resolveTargetPath(tax,category,filename): ruter via taksonomi getCategorySkill; null=ukjent→gate.

Prompt: scripts/kb-update/transform-prompt.md (doc→KB; husformat fra prompt-template.md, status-påstander eksplisitte for lag-5-gaten). Wiret i commands/kb-update.md §3.d (ny godkjent URL→fetch→destillér→header→validate→buildChange→lag5→resolveTargetPath→gate→atomisk) + §4.d (oppdateringer passerer validateKbFile). eval.mjs eksporterer nå evalSkill for kriterium-testen.

Kriterium møtt: «regenerer 1 fil → eval-score ≥ baseline» (test-transform-criterion.test.mjs). TDD: 12 lib-tester (inkl. import-invariant: ingen write-utils) + 2 kriterium FØR kode. Tester: validate 239 · kb-update 111 (+16) · kb-eval 15 (+2) · kb-integrity 115/115.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 22:31:26 +02:00
94a5d1bb14 feat(ms-ai-architect): Sesjon 5 carry-forward B — datoløse filer → unverified-tier
Rotårsak: en datoløs ref-fil fikk effectiveDate=0000-01-01 (alltid «stale») OG en path-basert prioritet (kunne bli critical) → flommet critical-bøtta og druknet genuint kritiske filer. Fix: ny unverified-tier deklarert i domain-taxonomy.json (lag 0, eneste sannhetskilde for prioritet).

makePriorityFn(tax) tar nå valgfri hasDate (default true → bakoverkompatibelt for eksisterende én-args-kallere); report-changes sender Boolean(fileDate). unverified rangerer sist i sorteringen — manglende dato er metadata-hygiene, ikke currency-hast. Ekte registry: 1 fil skilt ut som Unverified.

TDD: 4 tester FØR kode (test-priority-unverified.test.mjs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 22:31:25 +02:00
6af3624b17 feat(ms-ai-architect): Sesjon 4 - verifisering-ut (lag 5) + adversarial regresjonstest
Lag 5 kjører ETTER transformasjon (lag 4) og FØR en kandidat-endring skrives til
en KB-fil. Den fanger regresjons-klassen: en status-påstand «korrigert» mot en
tilfeldig sitert side og stille auto-applyet (den kjente agentic-retrieval-
regresjonen — hovedkontekst måtte rette manuelt).

Regel (spec §21): status-påstander (GA/preview/versjon/pris) flagges ALLTID for
operatør, aldri auto-applyet — uansett hvor sikker evidensen ser ut.

- lib/verify-out.mjs: ren klassifiserer, null deps (speiler decisions-io).
  detectStatusClaim(text) → {isStatus, kinds}; classifyChange(change) →
  {verdict: flagged|auto-applied, status_claim, reasons}. Tre flag-regler:
  status-gate (§21) · adversarial refutering · autoritets-mismatch (regresjonens
  rotårsak). Konservativ med vilje: ved tvil flagges. SKRIVER ALDRI.
- Fixtur tests/fixtures/kb-update/agentic-retrieval-regression.json: den kjente
  regresjonen (flat «GA» mot nyansert «delvis GA … resten preview»).
- TDD: 13 tester før kode, inkl. import-invariant (ingen write-utils).
- Wiret i kb-update.md §4 c2 (lag 5 mellom identifiser-endring og skriv).

Kriterium møtt: fixtur → flagged:true, ikke auto-applied.
Tester: validate 239 · kb-update 95 (+13) · kb-eval 13 · kb-integrity 115/115.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 22:00:36 +02:00
fe484ec323 feat(ms-ai-architect): Sesjon 3 - decision-ledger (lag 2) + discovery-dedup
Lukker discovery-løkken gjennom operatør-gaten. data/decisions.json er eneste
skrive-autoriserte bro mellom deteksjon og KB/registry; discovery LESER den og
utelater alt operatøren har tatt stilling til.

Dedup-policy = A (operatør-valg): isDecided = enhver ledger-entry (approved/
rejected/pending). Kun helt fraværende URLer re-foreslås.

- lib/decisions-io.mjs: createLedger/load/save(atomisk)/isDecided/recordDecision
  (ren)/filterUndecided. TDD: 10 tester før kode.
- discover-new-urls.mjs leser ledger, filtrerer, rapporterer deduped_by_ledger.
  Importerer ALDRI write-utils (invariant verifisert, 6 guard-tester).
- Gate dokumentert i kb-update.md §3b (eneste skrivevei).
- decisions.json tracket via gitignore-negasjon (som domain-taxonomy.json).

Kriterium møtt: dedup-diff (rejected re-foreslås ikke runde 2).
Tester: validate 239 · kb-update 82 (+16) · kb-eval 13 · kb-integrity 115/115.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 21:48:03 +02:00
d3af3f73c8 feat(ms-ai-architect): Sesjon 2 - ai-foundry->foundry registry-remap
Microsoft rebranet Azure AI Foundry -> Microsoft Foundry; doc-URLer flyttet
/azure/ai-foundry/ -> /azure/foundry/. Ny lib/registry-migrate.mjs (rene
funksjoner remapKey + migrateRegistry, 10 enhetstester) + one-shot
migrate-ai-foundry.mjs (backup via lib/backup.mjs + atomisk saveRegistry).

Remap: 164 ai-foundry-URLer -> foundry (2 probede DEAD-sider far eksplisitte
mal: evaluation-evaluators -> built-in-evaluators; agent-service ->
agents/overview). Remappede entries resettes til status=unpolled/lastmod=null
sa neste poll re-evaluerer. 1 kollisjon merget (ref_files unionert).
Schema-migrering: authority_source+course lagt til alle 1343 entries.
Idempotent. Registry er gitignored (regenererbar) - kun kode committes.

kb-update 66 tester gronne, validate 239.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 21:09:00 +02:00
eb2a002c2c feat(ms-ai-architect): Sesjon 2 - registry-skjema (authority_source + course reservert)
build-registry leser na **Source:**/**Primary source:**-header via ny
lib/kb-headers.mjs (parseSourceHeader, 7 enhetstester) og logger dekning
(0/N i dag). Hver URL-entry far reserverte felt authority_source:null +
course:null (bakoverkompatibelt). Populering med korrekt semantikk utsatt
til verifiseringslaget (lag 3) - minimal-reservert per operator-valg.

Eksisterende status-felt (poll: tracked/not_in_sitemap/unpolled) urort for
a unnga kollisjon. kb-update 56 tester gronne.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 21:05:54 +02:00
8bea3a224a feat(ms-ai-architect): Sesjon 2 lag 0 - konsolider taksonomi til en sannhetskilde
Ny data/domain-taxonomy.json (tracket via gitignore-negasjon; generert
registry/rapporter forblir ignorert) konsoliderer de 4 divergerende
taksonomiene: (a) sitemap-prefikser, (b) discover INCLUDE/EXCLUDE,
(c) category->skill, (d) getFilePriority. lib/taxonomy.mjs laster + kompilerer.

Refaktor: poll-sitemaps, discover-new-urls, report-changes LESER taksonomien
(ingen embeddede kopier). Kriterium grep TARGET_PREFIXES=[ == 0 oppfylt.

Konsolideringsfunn:
- category-skill-map.json stale i 4 entries (copilot-extensibility,
  monitoring-observability, performance-scalability, prompt-engineering ->
  sa engineering; disk sier advisor/governance/security/advisor). DISK er
  kanon. Map-en er ukonsumert av kode (kun README) -> flagget, ikke rort.
- discover fikk poll-paritet (12 -> 18 sitemap-prefikser).
- skill utledes na fra kanonisk category_skill -> ingen divergens (invariant-test).

Adferdsbevarende: 0 mismatch old vs ny prioritetslogikk pa 51 endrede filer;
discover sine hardkodede skill-verdier matchet allerede disk.
Tester: validate 239, kb-update 49 (+7 taksonomi), kb-eval 13 - alle gronne.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 21:02:59 +02:00
215772df87 feat(ms-ai-architect): Sesjon 1 - skill eval-baseline (rubrikk K1-K9) + ai-foundry probe
Read-only eval-verktoy scripts/kb-eval/eval.mjs (determ. K2/K3/K5/K6 + ref-tall) + operator-gated LLM-judge (judge-prompt.md -> data/judge-results.json) flettet til data/eval-baseline.json. 13 enhetstester (tests/kb-eval/), 42 kb-update-tester gronne. Baseline: K5 3/5 fail, K9 4/5 fail, K4 2/5 fail, ref-tall 2/5 fail; 2 konkrete bugs flagget (security 6x5-vekting-motstrid, governance broken ref-path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-19 20:26:56 +02:00
6e1fc6d37c fix(ms-ai-architect): #7d privat-sektor-paritet — sektor-parametrisering + onboarding-forgrening + 2 nye kommandoer (audit §5)
Audit §161-185: kjerne-dybden var sektor-agnostisk, men entry-points/kalibrering/
navigasjon var systematisk offentlig-sektor-først. Operatørvalg: full audit (kjerne
+ begge nye kommandoer). Telling 27→29 kommandoer. Ingen versjonsbump (→ #9-release).

Mekanisk kjerne:
- Sektor parametrisert i 6 kmd (classify/dpia/ros/review default nøytral m/offentlig-
  spesialisering; utredning beholder utredningsinstruksen + peker privat til :design;
  review får privat/regulert-gren DORA/Finanstilsynet). frontmatter-desc for review
  synket i CLAUDE/help.
- FRIA-scope KORRIGERT (verifisert mot AI Act Art. 27(1), WebSearch 2026-06-18):
  obligatorisk for (a) offentligrettslige organer, (b) private som leverer offentlige
  tjenester, (c) private deployere i kredittscoring (UNNTATT svindeldeteksjon) +
  livs-/helseforsikringsprising. Ikke lenger feilrådet som rent offentlig-verktøy.
- onboarding-agent forgrenet: sektortype (offentlig/privat) → private sektor-valg
  + privat reg-sett (DORA/Finansforetaksloven/IKT-forskrift/Verdipapirhandelloven);
  stiller ALDRI private om Offentleglova/Arkivloven. Sektortype skrevet til org-fil.
- requirements detekterer finans → DORA/Finanstilsynet (betinget §3-sjekkliste).

Nye kommandoer (refererer kun eksisterende kjerne-KB → ingen nye orphans):
- /architect:design — sektor-nøytralt Solution Architecture Document (mellombane
  mellom samtale og full utredning).
- /architect:vendor — tredjeparts/SaaS due diligence (dataresidens, sub-prosessorer,
  DPA, Schrems II/EDPB-TIA, AI Act-deployer).

Navigasjon/wiring:
- README: privat-enterprise-arbeidsflyt (eksempel 5) + DORA/FRIA-nyanse + design/vendor
  i tabeller + "Beyond Public Sector"-note.
- help.md: privat-bane i arbeidsflyt + design/vendor + manglende kb-update lagt til.
- CLAUDE.md-tabell: design/vendor + synket review/frimpact-desc.
- playground: katalog-oppføringer (produces_report:false), SHARED.sector utvidet med
  private sektorer, 2 privat-seeds (fraud-detection FRIA-unntatt + kredittscoring
  FRIA-pliktig). Telling 25/27→29 i playground/docs/README/test.

Tester: validate 239 PASS · playground v3 223 static / 390 kombinert · kb-integrity
115/115 · run-e2e alle suiter — 0 FAIL. CHANGELOG-«24 commands» bevart (historiske notater).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-18 18:27:51 +02:00
20c1be6531 fix(ms-ai-architect): #7c wire foreldreløse deliverable-KB — nye kommandoer businesscase + anskaffelse (I)
Audit P2 I. 6 foreldreløse deliverable-KB-er surfaces nå (var skrevet/betalt for, ikke nåbare).
Operatørvalg: dedikerte kommandoer (audit-primær), ikke kun dokumentasjon. Telling 25→27 kommandoer.

Nye kommandoer:
- businesscase.md → samfunnsokonomisk-analyse-nnv.md + gevinstrealisering-dfo-methodology.md (NNV + DFØ 5-stegs gevinst)
- anskaffelse.md → anskaffelser-ai-procurement-framework.md (kravspec, leverandørevaluering, terskelverdi)

Utvidet eksisterende:
- compare.md: weighted multi-kriterie-modus (alternativanalyse-methodology.md) ved 3+ alternativer / --weighted
- cost.md: kapasitet-/gjennomførbarhetssteg (gpu-compute-sizing.md + capacity-feasibility-benchmarks.md) ved --capacity

De-orphaning (kb-integrity måler orphan via SKILL.md/agents, ikke kommandofiler):
- ms-ai-governance/SKILL.md: ny seksjon 1.4 Beslutningsgrunnlag (3 referanser)
- ms-ai-advisor/SKILL.md: alternativanalyse + capacity-feasibility
- ms-ai-security/SKILL.md: gpu-compute-sizing
→ alle 6 de-orphaned (kb-integrity warnings 268→262)

Registrering/docs: help.md + README + CLAUDE.md-tabell + playground-katalog (2 produces_report:false-
oppføringer, gjenbruker ikke 14-parser/17-renderer-kanonen) + docs/playground.md (25→27) + test 25→27.

validate 231 PASS · playground v3 221 PASS · e2e alle suiter · kb-integrity 115/115 — 0 FAIL overalt.

NB: README:358/418/427 har pre-eksisterende «24 commands»-drift (uavhengig av denne endringen) — flagget for #8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
2026-06-18 17:50:06 +02:00
c08cb8d9e9 chore: roll up in-progress changes across plugins
- claude-design: scaffold new plugin (plugin.json, CHANGELOG, README)
- llm-security: playground design-system updates (tokens, components,
  tier3 supplement, new tier4 project-view CSS)
- ms-ai-architect: v2 mockup screenshots + local screenshot script
- voyage: annotate.mjs update

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 21:02:23 +02:00
9601c6a93b feat(ms-ai-architect): v1.15.0 — playground v3 project-view integration
Erstatter v2 project-surface (screen-tabs + category-tabs + per-command paste-cards)
med v3 renderProjectView (sidebar med 17 artifacts + main-area + import-modal overlay).
renderActive() ruter project-surface til renderProjectSurfaceV3() som wrapper
renderProjectView + topbar + app-shell.

V2-surface helt fjernet:
- renderProjectSurface (152 linjer)
- renderCommandSubCard (87 linjer)
- rehydratePasteImports (15 linjer)
- ACTIONS['project-screen'], currentProjectScreen
- 5 v2-CSS-klasser: .project-tabs, .project-tab*, .sub-zone, .paste-import-row, .project-header__*, .command-cards

Zombie-handlers beholdt for test-back-compat:
currentProjectTab, ACTIONS['project-tab'], ACTIONS['parse'],
handlePasteImport, window.__handlePasteImport. Unreachable fra v3 DOM
men nødvendige for test-playground-v3.sh + test-playground-parsers.sh.

2 fingerprint-gap lukket:
- requirements.headers: utvidet med "EU AI Act — Krav" pattern
- license.headers: utvidet med "Lisens-kapabilitetsmatrise" pattern
- KNOWN_GAP_FIXTURES = {} i test-playground-fingerprints.sh

migrateDataVersion utvidet med parserFor (3. arg):
- Demo-state med kun raw_markdown auto-parses til project.artifacts[cid]
- defaultParserFor(cmdId) resolverer PARSERS[archetypeFor(cmdId)]
- 3 bootstrap-callsites oppdatert (cold-load, import, load-demo)

Ship-QA bugfixes funnet via browser-dogfood:
- components-tier4-project-view.css lagt til i <link>-kjeden (var ikke loaded
  -> modal-overlay og two-column layout virket ikke)
- renderImportModal setter data-open="true" (DS-kontrakt for display: flex)

Bundler også sesjon 2-4 deliverables som ikke ble committed tidligere:
- shared/playground-design-system v0.6.0 (Tier 4 project-view CSS + 6 tokens)
- ms-ai-architect/playground/vendor/ re-sync til DS v0.6.0
- tests/test-playground-fingerprints.sh (sesjon 4 NY - 32 PASS)
- tests/test-playground-projectview.sh (sesjon 4 NY - 30 PASS)
- tests/test-playground-actions.sh (sesjon 4 NY - 19 PASS)
- tests/test-playground-migrations.sh utvidet (7 -> 16 PASS)
- tests/run-e2e.sh wirer alle 6 playground-suiter

Stats:
- bash tests/run-e2e.sh --playground: 386 PASS, 0 FAIL, 2 WARN (pre-eks)
- bash tests/run-e2e.sh (full): All E2E suites passed
- bash tests/validate-plugin.sh: 219 PASS

Screenshots regenerert til playground/screenshots/v1.15.0/ (24 PNG-er, 12
surfaces x 2 tema). Nye v3-surfaces: project-overview, project-artifact-*,
project-import-modal (viewport-only), project-search.

Docs oppdatert (3 nivåer): README.md (badge + version history),
CHANGELOG.md, CLAUDE.md (playground-seksjon + valideringstabell),
rot-README.md + rot-CLAUDE.md (marketplace-landingen + plugin-index).

.gitignore: ny pattern *.local.html + *.local.json for sesjon-state-filer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 20:58:51 +02:00
0a72499999 feat(ms-ai-architect): playground v1.14.0 — root-cause refaktor mot 10+ visuelle bugs
DS-konvensjon-adopsjon på 14 renderere over 6 sesjoner. Etter v1.13.0/.1
patchet 10+ symptomatiske visuelle bugs (191 linjer lokal CSS, 21
fix-kommentarer), grep v1.14.0 root-cause via DS v0.4.0 + per-renderer
refaktor.

Sesjon 2 — DS v0.4.0:
- B-DS-1: kanban-card word-break (break-all → break-word)
- B-DS-2: expansion title-main/sub display:block (var inline)
- B-DS-3: matrix-bubble cursor + hover/focus

Sesjon 3 — risk-renderere til DS-summary-grid + ros-layout
(renderDpia, renderSecurity, renderRos)

Sesjon 4 — 6 compliance/govern-renderere bytter .report-meta-wrapper
mot DS-konvensjon (renderAiActPyramid, renderRequirements,
renderConformity, renderTransparency, renderFria, renderReview)

Sesjon 5 — phase-renderere til expansion-list per fase
(renderMigrate, renderPoc — slett .phase-detail-CSS)

Sesjon 5b — lavt-scope renderer-fixes:
- renderCost: ekstraher .monthly fra p50/p90-objekter
  (key-stats viste \"[object Object]\")
- renderCompare: distinctive-token-matching erstatter firstWord-heuristikk
- renderUtredning: droppet misvisende role=\"tab\"

Sesjon 6 — ship: kommentar-kompaksjon (145 → 122 linjer), 24 screenshots
regenerert til v1.14.0/, dokumentasjon (3 nivåer), versjonsbump,
mellomfiler slettet.

Lokal style-blokk: 191 → 122 effektive linjer (~36% reduksjon)
DS bumpet til v0.4.0 (delt mellom plugins, andre re-syncer på eget tempo)
17 renderere PASS visuell QA mot demo-data i begge themes
219 plugin-validering, 272 E2E playground, 7 migrations PASS

Refs V1.14.0-PLAN + V1.14.0-AUDIT (slettet ved ship per plan).
2026-05-08 21:20:08 +02:00
080434d847 refactor(ms-ai-architect): playground v1.14.0 sesjon 3 — risk-rapporter til DS-konvensjon
- renderDpia: matrix wrappet i .card med h2
- renderSecurity: ros-layout (matrix+radar), small-multiples-section, top-risks som <ol> i .card
- renderRos: speil renderSecurity (5x5) + summary-grid for top-risks+recommendation
- renderFindingsBlock: fjern .report-meta-band-aid, bruk findings-section + findings__items--standalone
- Legg til .ros-layout, .summary-grid, .findings-section, .small-multiples-section i lokal CSS
- Fjern .top-risks fra defensive layout-block
- test-playground-v3.sh: bytt .findings__list → .findings__items i DS-klasse-asserts
- Style-blokk: 182 → 188 linjer (mål ≤195 nådd)

Refs V1.14.0-AUDIT.local.md sub-batch B + helper-section.
2026-05-08 20:13:00 +02:00
69cc501eba fix(ms-ai-architect): playground v1.13.0 — visuelle DS-bugs
Fix-pakke som speiler llm-security v7.6.1 (commit f9b555a). Samme klasse
visuelle bugs identifisert via parallell DS-analyse av playground-rendrere.

- B1: renderFindingsBlock + renderRequirements bytter <div class="findings">
  outer (DS grid 360px+1fr klemte indre struktur til 360px-kolonne, lot
  1fr-detail-panel-kolonnen stå tom) til <section class="report-meta">.
  BEM-strukturen findings__list > findings__group > findings__items uendret.
- B2: lokal .report-table CSS for 6+ rapporter (Trusler, Kostnadsoversikt,
  TCO, Risiko-tabell, Key Metrics) som manglet styling — DS implementerer
  ikke klassen. Speilet lokal styling fra llm-security v7.6.1.
- B3: ROS-matrise-bobler bytter <span> til <button type="button"
  data-threat-id="..." aria-label="..."> med document-level click-handler
  som scroller smooth til tilsvarende rad i Trusler-tabellen og
  highlighter raden i 1.6 sek. Lokal CSS for cursor:pointer, hover
  scale(1.15), :focus-visible outline.
- B4: renderRadarSvg bumpet 300x300 til 380x380, R fra 100 til 125,
  label-offset fra R+25 til R+28, dynamisk text-anchor basert på
  horisontal-posisjon for å unngå at bottom-labels overlapper hverandre
  ved 6+ akser (typisk for ROS-rapport med 7 risiko-dimensjoner).
- B5: lokal .recommendation-card__body { overflow-wrap: anywhere;
  word-break: break-word } for å forhindre at lange single-line tekster
  (URLer, owner-tags, dato) skubber innhold ut av viewport i grid-cellen.

tests/test-playground-v3.sh: DS-klasse-assertion oppdatert fra .findings
til .findings__list (BEM-list er fortsatt i bruk; outer grid-container
bevisst fjernet i B1).

Verifisering:
- 22/22 smoke-test PASS (B1-B5 grep-asserts)
- 271/271 playground E2E PASS (201 statisk-struktur + 70 parser-fixtures)
- 219 plugin-validering PASS
- 42 KB-update test PASS

Versjon: v1.12.0 -> v1.13.0 (plugin.json, README badge, README
version-history, CHANGELOG, ROADMAP, TODO, plugin CLAUDE.md
playground-header, root README plugin-list, root CLAUDE.md plugin-list).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 14:51:15 +02:00
665836caf1 test(ms-ai-architect): add ros-analysis fixture for E2E suite
Synthetic ROS-analyse output for "Acme Kunde-chatbot" (Acme Kommune)
following the same pattern as security-assessment, cost-estimation,
ai-act and summary fixtures. Satisfies all 29 assertions in
tests/test-ros-output.sh:

- 8 phases (Fase 1-8) plus Ledelsessammendrag
- 12 trusler i T-XXX-NN format (MAESTRO + OWASP-mapping)
- 9 risikoer i R-N format
- 10 tiltak i M-N format
- 7 ROS-dimensjoner med X/5-scoring
- 5x5 risikomatrise + restrisiko-tabell
- NS 5814 + ISO 31000 metodikk-referanser
- AI Act, GDPR, OWASP regulatoriske referanser
- MAESTRO + supply-chain referanser (Vedlegg O coverage)

Tar bort den siste pre-eksisterende run-e2e-feilen
(`bash tests/run-e2e.sh` exits 0).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 12:38:49 +02:00
78dcc6a16f feat(ms-ai-architect): v1.12.0 manuell KB-refresh — fjern launchd/cron-arkitektur
ToS-vurdering konkluderte med at autonom cron-kjøring er unødvendig kompleks
for en solo-fork-and-own-plugin. Apply-fasen krever LLM-resonnering uansett,
så manuell trigger fra en aktiv Claude Code-sesjon er enklere og holder
pluginen klart innenfor Anthropic Consumer Terms paragraf 3 (automated access
only via API key or where explicitly permitted — Claude Code CLI er
eksemptert som offisielt verktøy).

Lagt til:
- commands/kb-update.md — ny /architect:kb-update slash-kommando som driver
  poll, endringsrapport, microsoft_docs_fetch-update og commit fra sesjonen.
  Argumenter: --skip-discover, --priorities, --dry-run, --single-commit
- Catalog-entry i playground HTML for kb-update (categori: tool, 4 input-felt)

Slettet (Wave 3-5 reversert, ~1500 linjer + 7 testmoduler):
- scripts/install-kb-cron.mjs (cross-OS scheduler-installer)
- scripts/kb-update/weekly-kb-cron.mjs (cron-orkestrator med pre-flight, lock,
  backup, claude -p subprocess, post-run verify, rollback)
- scripts/kb-update/templates/ (4 scheduler-templates: launchd plist, systemd
  service+timer, Windows ps1 + README)
- scripts/kb-update/lib/auth-mode.mjs (cron-spesifikk auth validation)
- scripts/kb-update/lib/lock-file.mjs (PID+mtime stale-detection)
- scripts/kb-update/lib/cost-estimat.mjs (pre-flight budget-cap)
- 7 testmoduler under tests/kb-update/ for slettet kode
- tests/test-kb-update.sh (Bash-3.2-shim, erstattet av direkte node --test)

Beholdt (utility-laget fortsatt brukbart):
- run-weekly-update.mjs, report-changes.mjs, build-registry.mjs,
  discover-new-urls.mjs (KB change-detection-pipelinen)
- lib/atomic-write, lib/backup, lib/cross-platform-paths, lib/log-rotate
- 4 testmoduler (42/42 tester PASS)

Endret:
- hooks/scripts/session-start-context.mjs: fjern kb-update-status.json-overvaaking
- tests/run-e2e.sh --kb-update kaller node --test direkte i stedet for shim
- README.md, CLAUDE.md: KB-vedlikehold-seksjon rewriter for manuell modell
- plugin.json: 1.11.0 -> 1.12.0
- Rot README + CLAUDE.md: ms-ai-architect-versjon bumpet

Schedulering er bevisst utenfor scope og overlatt til brukeren — eventuelle
forks som vil ha periodisk varsling kan sette opp egen cron / launchd /
GitHub Actions som kjører rapport-fasen og varsler om aa kjore
/architect:kb-update i CC-sesjon.

Verifisering:
- bash tests/validate-plugin.sh: 219 PASS, 0 FAIL
- bash tests/run-e2e.sh --kb-update: 42/42 inner + suite PASS
- bash tests/run-e2e.sh --playground: 271/271 PASS (statisk + parsers)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 12:03:45 +02:00
51eff8efeb feat(ms-ai-architect): wire kb-update test suite into run-e2e dispatch [skip-docs]
Step 12 — adds --kb-update flag to tests/run-e2e.sh and a Bash 3.2-compatible
shim test-kb-update.sh that runs `node --test tests/kb-update/*.test.mjs`
(shell-glob form; Node 25 rejects directory-form arguments). Shim translates
node --test exit code + parsed pass/fail counts into the e2e-helpers.sh
suite counters (init_suite/print_summary).

Verification:
- Playground baseline 271 PASS unchanged before/after edit
- bash tests/run-e2e.sh --kb-update: exits 0, 110/110 inner tests pass
- bash tests/run-e2e.sh --all: kb-update suite included
- Pre-existing ROS-fixture absence (tests/fixtures/ros-analysis/) is
  unrelated to this change and remains for separate handling

Wave 5 of 7 in v1.12.0 auto-KB-update plan.
Plan: .claude/projects/2026-05-04-kb-update-fork-and-own/plan.md (Step 12)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 11:32:47 +02:00
4a7d3cc40c feat(ms-ai-architect): add install-kb-cron standalone helper for cross-OS cron registration [skip-docs]
Step 11 of v1.12.0 plan (.claude/projects/2026-05-04-kb-update-fork-and-own/plan.md).

scripts/install-kb-cron.mjs lives at the scripts/ root (not inside
scripts/kb-update/) because it is a plugin-wide install tool, not part of
the KB-update pipeline itself. Reads the appropriate template from
scripts/kb-update/templates/, fills {{NODE_BIN}}, {{PLUGIN_ROOT}},
{{LOG_FILE}}, {{SCHEDULE_HOUR/MINUTE/DAY_OF_WEEK}} placeholders, writes
to the platform-specific scheduler dir, and registers the job:

  macOS  - launchctl bootstrap gui/<uid> <plist>  (load -w fallback)
  Linux  - systemctl --user daemon-reload && enable --now <timer>
  Windows - powershell -ExecutionPolicy Bypass -File <ps1>  (beta)

Flags: --print-only, --target macos|linux|windows, --uninstall, --purge,
--node-bin, --claude-bin, --schedule "M H * * D" (default: Wed 04:23).

UID resolution for launchctl is guarded by process.getuid() POSIX-only
(undefined on Windows). MCP server presence in ~/.claude.json is
warning-only per brief Spørsmål 7. WSL detected via /proc/version.
Cross-OS rendering supported via --print-only --target <other>; install
on a non-host target rejects with explicit error.

11 subprocess + filesystem-snapshot tests in
tests/kb-update/test-install-cron.test.mjs verify --print-only produces
filled templates with no unsubstituted {{...}} placeholders, --print-only
writes nothing under HOME, --uninstall is idempotent on an empty HOME,
--schedule substitutes correctly, and invalid flags reject with non-zero
exit. Tests never invoke launchctl/systemctl/Register-ScheduledTask
against real schedulers.

Tests: 110/110 pass (was 99 before this step).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 11:26:54 +02:00
9a8e461a2b feat(ms-ai-architect): session-start hook reads kb-update-status for failure surfacing [skip-docs] 2026-05-05 11:12:37 +02:00
e9051ea5f5 feat(ms-ai-architect): rewrite weekly-kb-cron with portable paths, auth-mode-aware pre-flight, lock+backup+rollback [skip-docs] 2026-05-05 11:10:17 +02:00
ec2f92b608 feat(ms-ai-architect): add cross-OS scheduling templates (launchd/systemd/Windows) [skip-docs] 2026-05-05 11:02:44 +02:00
c70c682553 feat(ms-ai-architect): add lib/log-rotate for bounded log disk use [skip-docs]
Foundation lib for v1.12.0 cron rewrite — closes brief deliverable
"log-rotate" that was missing from the original plan (Phase 9 scope
revision). Standard logrotate idiom, zero dependencies.

- rotateLog(logPath, opts) returns {rotated, dropped, kept}
- Defaults: maxSizeBytes 10 MB, maxGenerations 5 (1 active + 4 rotated)
- No-op when log missing or under threshold
- Over-size: drop oldest, shift .N..1 down by one, move active → .1
- maxGenerations=1 keeps only the active slot (no rotated copies)
- Pure stdlib fs.renameSync chain with silent try/catch on missing gens

8/8 tests pass: missing/under-size/over-size paths, chained 6 rotations
capped at maxGenerations, oldest dropped, two-step content shift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:54:50 +02:00
ba3bb9778d feat(ms-ai-architect): add lib/auth-mode for cron-safe auth detection [skip-docs]
Foundation lib for v1.12.0 cron rewrite. Detects which Claude auth mode is
in scope and rejects modes that are architecturally incompatible with cron.

Resolution order:
- ANTHROPIC_API_KEY env-var → 'api-key'
- CLAUDE_CODE_OAUTH_TOKEN env-var → 'long-oauth'
- ~/.claude.json onboarded + runner exit 0 → 'subscription-browser-only'
- otherwise → 'unauthenticated'

Subscription browser-OAuth tokens expire ~15h and cannot survive cron — the
detector flags them explicitly so validateAuthForCron throws EAUTHCRON with
a remediation message pointing to `claude setup-token` or ANTHROPIC_API_KEY.

Both runner (subprocess invoker) and claudeJsonPath (~/.claude.json) are
dependency-injected. Tests stub them — no real subprocess spawn, no home-
directory reads.

15/15 tests pass: precedence, env-var detection, onboarded subscription,
non-onboarded fallback, validateAuthForCron throw paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:52:53 +02:00
215f5c1791 feat(ms-ai-architect): add lib/backup with sentinel-guarded rollback [skip-docs]
Foundation lib for v1.12.0 cron rewrite skill-tree backup/restore.
Zero dependencies. Uses fs.cpSync (recursive + preserveTimestamps) without
dereference (Node 22.17.x regression) and without filter (Windows symlink-
type bug).

- backupDir(srcDir, backupRoot, opts) → {backupPath, retentionDays, restore()}
- Backup-id format YYYY-MM-DDTHH-MM-SS (filesystem-safe; no colons)
- .backup-meta.json sentinel written as first action inside backupPath
- restore() writes .rollback-in-progress at backupRoot BEFORE rmSync+cpSync
  so a crashed restore leaves the sentinel for the next run to detect
- detectStaleRollback(backupRoot) — boolean predicate over sentinel
- cleanupOldBackups(backupRoot, retentionDays) — 3-step age resolution:
  meta.created_at → dir mtime → skip-with-warning (never delete a dir
  whose age cannot be established)

12/12 tests pass: timestamp format, content round-trip, sentinel lifecycle,
retention, mtime fallback, unparseable-meta skip, missing-root no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:50:10 +02:00
b39747d124 feat(ms-ai-architect): add lib/lock-file with PID+mtime stale detection [skip-docs]
Foundation lib for v1.12.0 cron rewrite. Atomic exclusive create via
fs.writeFileSync('wx'); on EEXIST resolves staleness with OR semantics:
stale if PID is dead OR mtime exceeds threshold. Either alone breaks the
lock — handles SIGKILL orphans (mtime), PID-reuse races (mtime), and
crashed-then-replaced runs (PID).

- acquireLock(lockPath, opts) → {lockPath, release()}
- staleThresholdMs default 1h; refreshIntervalMs opt-in for long runs
- registerCleanup default true (exit/SIGINT/SIGTERM/SIGHUP/uncaughtException)
- isPidAlive uses kill(pid, 0) with EPERM-as-alive nuance

12/12 tests pass: PID liveness, fixture concurrency, idempotent release,
stale variants (dead+old, live+old, fresh+live), staleThresholdMs honored.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:47:05 +02:00
f35f2bd605 feat(ms-ai-architect): add lib/cost-estimat heuristic for API-key budget [skip-docs]
Pure auth-mode-aware cost estimator for v1.12.0 cron pre-flight.

Heuristic: critical+high files only (medium/low excluded per brief);
3000 input + 1500 output tokens per file at Sonnet pricing
($3/M in, $15/M out).

Auth-mode behavior:
- api-key:   numeric usd, kvote_warn off  (subject to dollar-cap)
- long-oauth, subscription-browser-only:
             usd null, kvote_warn on      (quota, no dollar billing)
- unauthenticated/missing: best-effort api-key estimate

11/11 tests pass; covers both billing modes plus token-math
invariance across auth-mode (auth only affects dollar-field, not tokens).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:34:37 +02:00
53129e813d feat(ms-ai-architect): add lib/atomic-write for crash-safe state files [skip-docs]
Foundation lib for status-fil + lock-fil writes in v1.12.0 cron rewrite.
Pattern: writeFileSync to <path>.tmp.<pid>.<random> then renameSync to
target. Defends against half-written files; readers either see the
previous version or the new one, never a partial.

- atomicWriteSync(path, content) — string or Buffer
- atomicWriteJson(path, obj) — 2-space indent, trailing newline
- Windows EEXIST/EPERM defensive fallback (unlink target + rename)
- Best-effort tmp cleanup on writeFileSync failure
- crypto.randomInt(0, 2**32) two-arg form (unambiguous across Node)

9/9 tests pass including 50-way concurrent-write fuzzer (async-aware
withTmp helper).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:32:13 +02:00
6c4e1b6b82 feat(ms-ai-architect): add lib/cross-platform-paths for cache/log/state/backup dirs [skip-docs]
First foundation lib for v1.12.0 auto-KB-update. Resolves per-OS paths:
- macOS: ~/Library/{Caches,Logs,Application Support}/<app>/
- Linux: XDG_CACHE_HOME / XDG_STATE_HOME with ~/.cache, ~/.local/state fallbacks
- Windows: %LOCALAPPDATA%\<app>\{Cache,Logs,State}

Plus getBackupDir(pluginRoot) → <pluginRoot>/.kb-backup (gitignored).

All four functions auto-mkdir target. Dependency-injection via opts
({platform, homedir, env}) makes the lib pure-testable; 13/13 tests
pass under tmpdir isolation without touching real ~/ paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:30:31 +02:00
dfa387aba2 feat(ms-ai-architect): release v1.11.0 — design-system 100%-adoption + visual upgrade
Sesjon 3 av 3 — leverer Fase 7-9 av v1.11.0-planen.

Fase 7 (Acme-rename på demo-state):
- Rename "Acme AS" → "Acme Kommune" og "Demosystem" → "Acme Kunde-chatbot"
  konsistent på tvers av alle 17 fixtures.
- build-demo-state.mjs: organization.name → "Acme Kommune", projects[0] →
  id "acme-kunde-chatbot" / name "Acme: Kunde-chatbot".
- Re-bygd demo-state-v1-blokk i playground HTML.

Fase 8 (Screenshots-regenerering):
- 24 nye PNG-er under playground/screenshots/v1.11.0/ (12 surfaces × 2 tema,
  retina, fullPage). v1.10.0-mappen beholdt som historisk referanse.
- tests/screenshot/run.mjs: OUT_DIR + kommentarer bumpet til v1.11.0.

Fase 9 (Release: docs + versjonsbump):
- plugin.json 1.10.1 → 1.11.0.
- README.md (plugin): version-badge + Version History + screenshot-gallery refs +
  demo-data refs oppdatert.
- CLAUDE.md (plugin): Playground-overskrift v3/v1.10.0 → v3/v1.11.0,
  Demo system-seksjon v1.10.1 → v1.11.0, screenshot-refs v1.10.0 → v1.11.0,
  "Inline CSS-kandidater" konvertert til "Design-system 100%-adoption" status.
- Root README.md: ms-ai-architect-versjon 1.10.1 → 1.11.0, demo-tekst og
  Playground-tekst regenerert for v1.11.0, "271 PASS combined" → "278 PASS".

Verifisering:
- bash tests/run-e2e.sh --playground → 271/271 PASS (static + parsers).
- bash tests/test-playground-migrations.sh → 7/7 PASS.
- Total: 278/278 PASS, 0 FAIL.

Refs: NEXT-SESSION-PROMPT.local.md (Sesjon 3 av 3, plan
.claude/plans/jeg-skal-pr-ve-effervescent-token.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 17:41:36 +02:00
a60e3c7cd5 feat(ms-ai-architect): v1.11.0 Sesjon 2 — design-system 100%-adoption (Fase 4-6) [skip-docs]
Migrerer alle 6 PARALLEL CSS-navn i playground HTML til DS-konvensjon:
- .topbar*           -> .app-header*               (DS components.css)
- .residual-pair*    -> .pair-before-after*        (DS components-tier3.css; data-severity -> BEM modifier)
- .command-card*     -> .card + .card__*           (DS base.css + tier3-supplement; outer + 4 sub-elementer)
- .catalog-card*     -> .card + .card__*           (samme; outer + 7 sub-elementer)
- .screen-tabs/.screen-tab/.screen
                     -> .tab-list/.tab/.tab-panel  (DS tier3-supplement; data-active="..." -> [hidden]-attr)
- .pyramide-desc*    -> .stack-sm + .pyramide-tier-detail*
                                                   (DS tier3-supplement section 22+23)

Trimmer plugin-local <style>-blokk fra 202 -> 127 linjer (37% reduksjon):
- Sletter inline duplikater av DS v0.3 sections 14-15 (.page__*, .key-stats, .key-stat--{level})
- Sletter inline duplikater av sections 18-19 (.top-risks, .recommendation-card)
- Refaktorerer renderPageShell + renderKeyStatsGrid til DS markup-pattern
  (.page__header-main + .page__header-aside + .page__title h1; .key-stat--{level} BEM)

Beholdt eksplisitt plugin-local (med dokumentasjon i CSS-kommentarer):
- .verdict-pill (domain-semantikk go/block — distinkt fra DS .verdict-pill-lg severity-band)
- .scenario-card[data-status="met/partial/missing"] (DS har kun "winner")
- .read-more-block + .suppressed-panel (native <details>; DS bruker JS-toggled aria-expanded)
- .onboarding-*, .home-*, .project-*, .modal*, .command-form*, .catalog-cards (plugin-spesifikk layout)

Visuell oppgradering (Fase 6):
- Eyebrow-label "PROSJEKTER · X av X" over home-projects seksjon
- .card--severity-{positive/medium/critical} venstre-border på rapport-cards basert på
  parsed.verdict (go/approved/allow=positive, go-with-conditions/warning=medium,
  block/failed=critical) — visuell signal for rapport-status i project surface
- AI Act-pyramide bredde min-width: 480px + tier-label font-size: var(--font-size-md)
  for å fjerne tekstklipping ("Uakseptabe...", "klassifisert"). Responsive @media for <560px.
- App-header-restruktur: brand + breadcrumb + spacer + actions (DS pattern), ikke flex-between
- .stack-lg vertikalt rytme-utility på home/project/catalog body i renderPageShell

Tests oppdatert for nye DS-navn:
- Step 10: residual-pair -> pair-before-after assert
- Step 12: screen-tabs -> tab-list assert (class="tab-list" eksplisitt)

Verification: 201 + 70 + 7 = 278/278 PASS, 0 FAIL.
6 intentional plugin-local residuals (1 .catalog-cards container + 4 .read-more-block + 1 .suppressed-panel)
— alle dokumenterte i inline <style>.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 16:46:40 +02:00
834b438397 feat(ms-ai-architect): release v1.10.1 — demo system + screenshot gallery
Adds one-click demo and committed screenshots so forkers see what the plugin
produces without running anything. Plugin contract unchanged.

- Inline <script id="demo-state-v1"> block (37 KB) built by
  scripts/build-demo-state.mjs from playground/test-fixtures/*.md
- "Last inn demo-data" button on onboarding (replaces all state with demo)
- raw_markdown persistence on project.reports[id] with equal-value guard
- rehydratePasteImports() auto-fills textareas + re-renders visualizations
  on project surface mount
- tests/screenshot/ standalone Playwright runner (own package.json)
- 24 committed screenshots in playground/screenshots/v1.10.0/
  (12 surfaces x 2 themes, deviceScaleFactor 2 retina, fullPage)

Tests: 215 + 201 + 70 + 7 = 493 PASS, no regressions.

Docs updated per OBLIGATORISK three-level rule (plugin README, plugin CLAUDE,
marketplace root README, CHANGELOG).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 09:24:02 +02:00
8cbdeb15c1 feat(ms-ai-architect): renderer batch C (econ + docs 8) + structural test asserts [skip-docs]
Sesjon 5 av v1.10.0-løpet (8 av 17 renderers wrapped med renderPageShell).
Nå alle 17 renderers bruker felles grunnskjelett (page__eyebrow + h1 + verdict).

Renderers wrapped:
- C.1 renderCost: eyebrow=KOSTNAD, key-stats utvidet med DOMINERENDE-komponent
- C.2 renderLicense: eyebrow=LISENS, scenario-card-grid per kandidat-lisens,
  TOPP-LISENS key-stat
- C.3 renderMigrate: eyebrow=MIGRASJON, E2 mat-ladder erstatter aiact-timeline,
  E4 cycle-ribbon ved aktiv fase
- C.4 renderAdr: eyebrow=ADR, D4 critique-card per beslutningsseksjon, ADR-status
  → verdict-pille (accepted/proposed/rejected/deprecated)
- C.5 renderSummary: eyebrow=SAMMENDRAG, E8 read-more for lange rationale
- C.6 renderPoc: eyebrow=POC, E2 mat-ladder + B5 traffic-light per success-kriterie,
  pocVerdict styrer verdict-pille
- C.7 renderUtredning: eyebrow=UTREDNING, A4 screen-tabs (Bakgrunn/Funn/Konklusjon/
  Anbefaling) + E8 read-more på lange seksjoner
- C.8 renderCompare: eyebrow=SAMMENLIGN, D1 scenario-cards-grid per kandidat,
  parseComparison.winner styrer vinner-pille + VINNER key-stat

Parser-utvidelser (R15 forward-compat — eksisterende fixtures uendret):
- parsePhasedPlan: phases[].status (planned/active/done), currentPhaseIndex,
  pocVerdict (kun ved POC-Verdict-linje)
- parseComparison: optional winner-felt fra "## Vinner: <id>"-linje

Topic 2 strategi A i handlePasteImport: sentralisert _consumer-tildeling
(result.data._consumer ||= cmd.id), respekterer parser-spesifikk verdi
(parseMatrixRisk → 'ros').

Fixture-updates: migrate/poc med Status: per fase + POC-Verdict, compare med
"## Vinner:"-linje.

Test-asserts (tests/test-playground-v3.sh +18 PASS, totalt 201/201):
- 25e SC8 per-renderer for batch C (8 renderers)
- 25f Step 12 must_contain (mat-ladder, screen-tabs, _consumer)
- 25g Felles grunnskjelett: alle 17 renderers bruker renderPageShell
- 25h Tier 3-bruk: kanban i conformity/review, mat-ladder i migrate/poc
- 25i Onboarding field-distribution (4 strukturerte, 14 fritekst)

Verifisert: 201/201 statiske, 70/70 parser-fixtures, 7/7 migrations PASS.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 07:52:52 +02:00
298a5d04e9 feat(ms-ai-architect): renderer B.3 review adopt page-header + kanban (Keep/Review/Remove) + suppressed-panel
- parseFindings utvidet med status-felt-deteksjon og buckets-mapping {keep, review, remove, suppressed}
- Eksplisitt status vinner; severity-fallback (kritisk/høy → review, medium/lav → keep)
- Norsk og engelsk status-vokabular støttet (suppress/waive/akseptert, behold/keep, tilsyn/review, fjern/remove)
- renderReview wrapper renderPageShell med eyebrow=REVIEW; bytter findings-listen til E1 kanban-board (3 kolonner Keep/Review/Remove)
- E6 SUPPRESSED-panel som collapsible details for waived/akseptert items
- KeyStats utvidet med KEEP/REVIEW/REMOVE-stats
- review.md fixture utvidet med Status-kolonne (1 remove, 4 review, 2 keep, 2 suppressed)

Pluss test-utvidelser:
- Seksjon 25c: SC8 per-renderer verdict-pill assert for Sub-batch B (renderSecurity, renderRos, renderReview)
- Seksjon 25d: Step 11 must_contain — top-risks + suppressed >=1 treff
- Test-suite gar fra 178 -> 183 PASS

[skip-docs]
2026-05-04 06:35:38 +02:00
9fdcd8938f test(ms-ai-architect): SC8 per-renderer verdict-pill + Step 10 must_contain asserts
- Seksjon 25a: per-renderer verdict-pill assert for de 6 Sub-batch A-rendererene (R7)
- Hver awk-ekstraherer body og krever data-verdict ELLER renderPageShell-kall
- Seksjon 25b: Step 10 manifest must_contain — kanban-board + residual-pair >=1 treff
- Test-suite gar fra 170 -> 178 PASS i Playground v3 Static structure
2026-05-04 06:12:23 +02:00
d137161090 feat(ms-ai-architect): renderer A.4 frimpact adopt page-header + critique-cards
- renderFria wrapped med renderPageShell (eyebrow FRIA, lede ref AI Act Art. 27)
- Erstatter rights-matrix med D4 critique-cards per rettighet (severity fra impact-score)
- Ny fria-case i inferVerdict: max impact >=4 block, >=3 warning, ellers go-with-conditions
- DS_CLASSES test oppdatert: rights-matrix -> critique-card (Step 10 endrer body for FRIA)
2026-05-04 06:06:28 +02:00