feat(ms-ai-architect): C3.6 — SessionStart-surfacing av kurs-leads (summarizeCourses) → C3 kurs-spor komplett (TDD)

Siste C3-fase. `summarizeCourses(report)` ren one-liner i detection-schedule.mjs
(«Kurs-signaler: N nye / M endrede kurs i dekkede produkter»; null ved
0/skipped/error/removed-only/malformed — removed er informasjons-signal, aldri
surfacet lead, spec §4.2). Speiler summarizeSkillLifecycle.

Wiring i session-start-context.mjs: read-only, leser
scripts/kb-update/data/course-detection-report.json, foreslår /architect:kb-update,
speiler skill-signaler-blokka. Hooken spawner ingenting for kurs-sporet.

docs/development.md: ny C3-workflow-seksjon (to-stegs: Claude-fri deteksjon →
SessionStart-surfacing → operatør-gate §3c). CLAUDE.md hook-tabell oppdatert.

Tester (+6): summarizeCourses — new+updated one-liner, only-new/only-updated,
zero→null, removed-only→null, skipped/error→null, missing/partial→null.
kb-update 307→313, validate 239/0, kb-eval 100/0, hooks 11/11, discovery 13/13.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-06-23 15:00:40 +02:00
commit f4dd4d3fb6
5 changed files with 120 additions and 1 deletions

View file

@ -10,6 +10,7 @@ import {
loadScheduleConfig,
shouldRunDetection,
summarizeSkillLifecycle,
summarizeCourses,
} from '../../scripts/kb-update/lib/detection-schedule.mjs';
import {
resolveOrgDir,
@ -188,6 +189,20 @@ if (existsSync(skillReportPath)) {
}
}
// Course-detection signals (Spor C / C3.6) — read-only one-liner; never spawns.
// A lead is a signal that a topic exists, not auto-ingest: surfacing it here
// invites the operator to run /architect:kb-update §3c, which gates the lead
// into the courses ledger. Mirrors the skill-signaler block above.
const courseReportPath = join(pluginRoot, 'scripts', 'kb-update', 'data', 'course-detection-report.json');
if (existsSync(courseReportPath)) {
try {
const courseSummary = summarizeCourses(JSON.parse(readFileSync(courseReportPath, 'utf8')));
if (courseSummary) parts.push(`${courseSummary}. Kjør /architect:kb-update`);
} catch {
// Ignore — advisory only
}
}
if (nearestDeadline) {
parts.push(`EU AI Act: ${nearestDeadline.daysLeft} dager til ${nearestDeadline.label}. Kjør /architect:classify`);
}