0903e3a8d17ff3e162a70756a424d11cf491c331
1727 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0903e3a8d1 |
perf(ai-sdk): embed query once across router fan-out + fold umlauts in intent/concept matching
CI / detect-changes (push) Successful in 5s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 5s
CI / validate-canonical-controls (push) Successful in 4s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m0s
CI / test-go (push) Successful in 59s
CI / iace-gt-coverage (push) Successful in 17s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
Authority Router re-embedded the query per collection (6x); on dev the embed endpoint (OVH) is remote so that was 6 round-trips = 7-12s per /retrieve. Embed once, reuse via ctx across the concurrent per-collection searches. DetectIntent + ConceptNorms now fold ae/oe/ue/ss so ASCII (Pruefe) and umlaut (Pruefe) inputs both match. |
||
|
|
cf2cea437e |
merge(admin): FE Evidence-Workspace → main (evidence-framed header + bindingness)
CI / detect-changes (push) Successful in 5s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 4s
CI / validate-canonical-controls (push) Successful in 4s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m2s
CI / test-go (push) Successful in 1m0s
CI / iace-gt-coverage (push) Successful in 15s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
75501d106a | merge(ai-sdk): Advisor Reasoning Stack → main (Clarity+G1+Concept+Scope+Term+Intent) | ||
|
|
e901447096 | feat(ai-sdk): Advisor Reasoning Stack — Clarity+G1+Concept-Injector+Context-Scope+Term-Resolution+E4-Curation+Intent-Signal | ||
|
|
a9b04e5286 |
feat(advisor): evidence-framed header + bindingness contract seam
Rework the Compliance Advisor header ("Diese Antwort stuetzt sich auf")
to describe the EVIDENCE rather than the documents: binding
Rechtsgrundlagen split from Leitlinien (soft-law guidance), a
per-regulation breakdown, plus Abbildungen, Fussnoten and Evidence Units.
No fabricated trust score — objective counts only.
- bindingness is a canonical Legal-KG fact (APEX rule): added an optional
EvidenceUnit.bindingness contract seam; the FE renders the split from it
and degrades to a neutral per-regulation breakdown when it is absent
(SDK/RAG asked via board to populate it in /retrieve).
- evidence-grouping.ts: pure, tested grouping/counting model.
- route.ts: optional `audience` field (tonality) kept out of the retrieval
question; answers lead with a "Kurz gesagt" summary, structured by theme.
- E2E + unit tests updated for the evidence framing.
Not deployed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
62da36872f |
docs(citability): generische Legal-Reference-Hülle als Phase-B-Design-Vorgabe
User-Ergänzung: norm_ids sind nur die erste Rechtsreferenz-Art. Runtime-Vertrag (Phase B)
soll eine erweiterbare Hülle tragen (legal_reference: {norm_ids, citation_units, recital_ids,
guidance_ids, case_law_ids, interpretation_ids}), damit neue Referenz-Arten additiv als
optionale Keys landen ohne erneuten Vertrags-/Go-Struct-Umbau. Naming-Hinweis: NICHT
"legal_basis" (kollidiert mit dem Obligation-Array). Bindend ⊥ Guidance bleibt erhalten.
Phase B baut NUR norm_ids; Rest = reservierter Platz, kein Bauauftrag. Nur Spec, kein Code.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
2a8abb6235 |
docs(citability): Weg-1 Datenbereitschaft dokumentiert (Obligation->Norm), UI deferred
User-Auftrag: Datenbereitschaft für Weg 1 bestätigen + dokumentieren, KEIN UI bauen.
Neuer Spec-Abschnitt "Weg 1 — Obligation->Norm-Zitierfähigkeit":
- Zwei Zitierebenen getrennt: RAG-Evidence-Zitat (Advisor heute, /retrieve) ⊥
Obligation->Norm-Zitat (norm_id-Join, diese Registry) — beide langfristig nötig.
- Datenbereitschaft: obligation norm_ids READY (62/64 joinbar) + KB-v2-Ziele bestätigt;
GAP = Runtime-Vertrag obligation_join_keys.json trägt norm_ids NICHT (nur citation_units),
Go ObligationKey ohne NormIDs, AssessObligationStatus setzt CitationSpans:"pending" hart.
- Deferred-Sequenz (nicht gebaut): 1 Data-Prep norm_ids->join_keys (Domäne 2) ->
2 Go-Build (CitationSpans aus norm_ids, koordiniert) -> 3 UI ("Diese Pflicht beruht auf ...").
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
f37081b60b |
test(advisor): E2E for the Clarity-Gate chain (Playwright, stubbed endpoint)
Per the "always write E2E" rule: drives the floating advisor widget end-to-end against a stubbed /api/sdk/compliance-advisor/chat with contract fixtures — clarify (L1 + context chips), answer ([n] citation + evidence pane), and clarify->pick-context->scoped-answer. No backend needed (route interception). Runs on CI/macmini (Next app on :3002); validated here via tsc + `playwright --list` (3 tests discovered). check-loc 0. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
4027470855 |
feat(pipeline): Scope-Audit als fester Review-Step (flag-only, non-blocking)
#3 (User): Scope-Audit in den Cut-Prozess aufnehmen — nicht-invasiv, nur flaggen, Reklassifizierung bleibt menschlich/koordiniert (betrifft join_keys + Compliance Execution). - validate_registry.py surfaced jetzt pro Cut authority-/institution-adressierte Obligations OHNE scope-Klassifikation als non-fatal Warnung (ändert Exit-Code NICHT, mutiert NICHT; importiert NON_MANUFACTURER_DOMAINS aus scope_audit.py, DRY). Verifiziert: clean-Fall (cra_machinery, 3 klassifiziert) still, Negativtest (sanctions ohne scope) feuert Warnung. - obligation_registry_v1.md: neuer Abschnitt "Scope-Audit (Review-Step, PFLICHT je Cut)" mit scope-Achse (in_scope/out_of_scope/derived_obligation), Gate-Regel verbatim und Werkzeug-Trennung FLAG (scope_audit.py) ⊥ MUTATE (apply_scope_classification.py, nur Review-Go). Gate: jeder neue Cut läuft durch Scope-Audit; Findings werden dokumentiert; automatische Reclassification verboten ohne explizites Review-Go. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
3f372bcb39 |
feat(advisor): Phase 1 — endpoint backward-compat (keep breakpilot-workspace working)
The advisor endpoint now serves two shapes off one orchestration:
- new FE ({question}) -> v3 JSON contract (clarity/answer/evidence/citations/...).
- legacy consumer ({message}, e.g. breakpilot-workspace which reads a text stream and
persists raw bytes) -> plain-text stream of the L2 answer (clean prose, no [n] markup,
no clarify gate). isLegacyRequest() discriminates; answerSystem() gains withCitations.
Prevents the v3 contract from breaking breakpilot-workspace's chat (CLAUDE.md rule #4,
keep every consumer working). No deploy. tsc clean, 13 vitest (incl. isLegacyRequest),
check-loc 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
6523286af6 |
feat(registry-quality): scope-Achse — 2 out_of_scope + derived_obligation (User Option 2)
User-Entscheidung 2026-07-01 zum Scope-Audit: Adressat der Norm != Handlungspflicht des Herstellers. Neue `scope`-Attribut-Achse (Enum, KEINE neue Objektklasse -> Freeze v1.0 unberuehrt): in_scope (default) / out_of_scope / derived_obligation. - sanctions + market_surveillance_safeguard -> out_of_scope (reine Staats-/Durchsetzungs- bestimmungen; Praezedenz CSIRT/ENISA im CRA-Vuln-Cut). Aus join_keys gefiltert. - notified_body_requirements -> derived_obligation (Norm adressiert primaer die notifizierte Stelle, erzeugt aber mittelbare Herstellerpflichten: NB einbeziehen + Unterlagen + Konformitaetsbewertung) + scope_split_candidate (spaetere Aufspaltung Normadressat <-> abgeleitete Herstellerpflicht). BLEIBT im Set (Prinzip: Wissen nicht zu frueh verwerfen). - export_join_keys.py filtert scope==out_of_scope + fuehrt scope je Eintrag -> join_keys 126->124 (MaschVO 31->29; 123 in_scope + 1 derived_obligation). - scope_audit.py jetzt 3-Wege-klassifikations-bewusst (0 unklassifizierte Reste) + apply_scope_classification.py (deterministisch). Fuer jeden kuenftigen Cut mitlaufen. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
e54d07f2d9 |
feat(registry-quality): Scope-Audit-Tool — Adressaten-Prüfung (Hersteller vs Behörde)
Generalisiert den Zitierfähigkeits-Befund (2 Kapitel-Obligations authority-facing) zu einem wiederverwendbaren Review-Stage-Werkzeug: flaggt Obligations, deren applicability an Behörde/notifizierte Stelle/Mitgliedstaat adressiert ist = out_of_scope-Kandidaten (Registry modelliert Hersteller-Pflichten; Präzedenz CSIRT/ENISA im CRA-Vuln-Cut). - scope_audit.py: deterministisch, key't auf applicability (Adressat), NICHT auf Behörden-Nennung im Namen → Melde-AN-Behörde-Pflichten bleiben korrekt IN-SCOPE (False-Positive-Guard, verifiziert an exploited_vuln_reporting_authorities). - 126 Obligations gescannt → 3 Kandidaten (alle MaschVO LEGAL_MINIMUM): notified_body_requirements (domain:notified_body) · market_surveillance_safeguard (domain:authority) · sanctions (domain:authority). - scope_audit_findings.json = Findings-Artefakt. Audit FLAGGT nur; Reklassifizierung = User/Owner-Entscheidung (ändert join_keys, cross-session). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
5a513181cc |
feat(advisor): Clarity-Gate orchestration in route.ts (consumes /retrieve)
Completes the advisor stack (FE + orchestration; /retrieve is SDK/RAG-owned). The route
now returns the FE contract instead of a text stream:
- retrieveFull() calls /retrieve with {query, context}; consumes clarity/evidence/
visual_evidence/footnotes (exact shape per board 2026-07-01 12:25).
- mode-routing (resolveMode): clarify unless a context was chosen and /retrieve's
clarity.mode says so. clarify -> L1 general answer (completeAdvisorAnswer, ungrounded,
no sources). answer -> L2 answer over numbered evidence with [n] markers.
- citations generated here ([n] -> nth evidence unit); footnotes remapped; evidence /
visual_evidence passed through.
- advisor-llm: non-streaming completeAdvisorAnswer(). Pure mappings in retrieve-mapping.ts
(+ tests). Removed the dead v2 evidence.ts/evidence-adapter (RegulationRef moved to
regulation-display). controls-augmentation kept (tested; re-integrable later).
NOT deployed: joint deploy with the SDK /retrieve endpoint (deploy-coupling). tsc clean,
25 vitest (mapping/clarify/answer/markdown/registry/rag), check-loc 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
a4cb104258 |
feat(citability): KB-v2-Verifikation der norm_ids einarbeiten (16/19 confirmed)
Feedback der Compliance/KB-Session (2026-07-01): die 19 verify_pending norm_ids gegen KB-v2 (bp_compliance_kb_2026_1_build) geprüft — 16/19 bestätigt (alle CRA+MaschVO-Artikel existieren). Die 3 fehlenden = Kapitel-Ebene (EU-MaschVO-KapitelIV/V/VI): der KB-Compiler mintet Artikel+Annex, KEINE Kapitel. - Artikel-norm_ids verify_pending -> article_confirmed (16 distinkt). - Kapitel-norm_ids -> chapter_no_kb_unit (danglender Join-Key) + norm_id_note (Re-Anchor auf Konstituenten-Artikel = Enhancement, KB-v2 hat sie; NICHT geraten). - 2 Kapitel-Obligations (notifizierte Stellen · Marktüberwachung/Schutzklausel, beide rein prozedural, obligation_id=None) citation_status norm_id_linked -> chapter_reanchor_pending. Joinbar bleiben 62 Obligations. - Status gesamt: 53 annex_confirmed + 10 article_confirmed + 2 chapter_no_kb_unit. - norm_id_manifest.json + Contract-Block um kb_v2_verification ergänzt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
808a7faea3 | Merge remote-tracking branch 'origin/main' into feat/obligation-aggregation | ||
|
|
ffbedfa0dc |
feat(citability): logischer norm_id-Join auf legal_basis (KB-v2 Zitier-Vertrag)
Wake-up #2 (Domaene 2): Zitierfaehigkeit ohne char-Level-Spans via logischem norm_id-Join auf KB-v2-Units (bp_compliance_kb_2026_1_build). Konvention (Board Compliance/KB-v2 2026-07-01): EU-<ACT>-Anhang<ROM> (Annex-Ebene, confirmed) / EU-<ACT>-Art<N> + EU-<ACT>-Kapitel<ROM> (verify_pending). Namensvariante EU-MaschVO-* (NICHT MaschinenVO). KEINE neue Klasse — norm_ids ist ein Attribut auf legal_basis (freeze-safe). - 65/65 legal_basis gejoint (CRA 40 + MaschVO 25), 0 unparsed; 64 Obligations citation_status -> norm_id_linked (BP/guidance-anchored bleiben ohne norm_id). - 53 annex_confirmed, 12 verify_pending; distinkt 5 Annex-IDs + 19 Art/Kapitel. - norm_id_manifest.json = KB-v2-Handoff (verify_pending Art-/Kapitel-IDs pruefen). - Granularitaet annex-grob (Part/Punkt = KB-Enhancement TBD); Artikel-norm_ids in KB-v2 noch zu verifizieren. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
f9b7ba2424 |
feat(advisor): v3 Clarity Gate — Case model + clarify/answer contract, [n] citations
Builds the FE against the SDK<->FE Clarity-Gate contract (board 2026-07-01 /
advisor-clarity-gate-contract). The advisor is now a CASE, not a chat:
- Request {question, context?}; response {mode: clarify|answer, clarity, general_answer,
answer, evidence, citations, visual_evidence, footnotes}.
- clarify mode: short L1 general answer (marked "allgemeine Definition, ohne Rechtsquelle")
+ domain context chips; picking a chip re-runs the case scoped (-> answer).
- answer mode: markdown answer with clickable [n] citation markers coupled to evidence
cards (highlight + scroll), evidence grouped by document family, visual_evidence
(visual_type), footnotes, honest summary counts (no trust score).
- FE never parses the answer for structure — only the deliberate [n] markers, mapped via
citations[]. New: contract.ts, useAdvisorCase, useCitationHighlight, ClarifyView,
EvidenceUnitCard, VisualEvidencePane, CaseView. Removed the v2 stream/chat components.
NOT deployed: FE shape-switch (JSON modes) must deploy TOGETHER with the SDK endpoint
delivering the contract (board deploy-coupling). Proxy/route.ts unchanged (SDK-owned).
tsc clean, 16 vitest (incl. clarify+answer fixtures), check-loc 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
591cae5ebc |
feat(advisor): Case Workspace v2 — Evidence grouping, human names, 3-column, summary
Reworks the advisor toward a Compliance Case Workspace (review feedback): - Rename user-facing "Quellen" -> "Evidence". - Evidence grouped by document/regulation family (count + expandable) — no more unsorted DSK/DSK/DPF/... jumble. - Human-readable regulation names via a display registry (DSK Sdm B51 -> "DSK Standard-Datenschutzmodell (SDM)" / Kapitel B51); generic, bridges G2. - Evidence summary "Antwort basiert auf" with meaningful counts; Regelwerke = distinct FAMILIES (fixes the inflated count). NO fabricated trust score (needs a defined basis). - Expanded mode = 3-column workspace (question+summary | answer | evidence, independent scroll) + history switcher; narrow mode stays stacked. - Prompt: push aggressive markdown structure (## per aspect, numbered phases). Deferred/coordinated on board: C8 diagrams (RAG contract), answer<->evidence coupling [1] (needs LLM citation anchors — phase 2), G1 retrieval relevance + G2 metadata (RAG). tsc clean, 17 vitest, check-loc 0. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
3884038b06 |
fix(advisor): generic — drop trailing source list in answer + de-duplicate source card
Two structural fixes (not query-specific): - Proxy prompt: forbid ANY trailing "Quellen:"/"Quellen im RAG-System" list and make it the LAST instruction so it overrides the soul file's answer-structure + example that teach a closing sources section. Applies to every answer. - KnowledgeUnitCard: render the label only when it differs from regulation.short, so a source whose label == short name no longer prints twice. Applies to every source. Answer text is still never parsed in the FE (sources live in the pane). + card test. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
a606000a20 |
feat(ai-sdk): EvidenceType-Schicht — autoritative Fußnoten/Tabellen/Figuren surfacen
Router-Schicht Intent→KnowledgeSpace→EvidenceType→Collection→Merge→Authority (User-
Entscheidung A generalisiert). Neuer EvidenceType{TEXT,FOOTNOTE,TABLE,FIGURE} +
classifyEvidence (aus is_footnote/is_table/is_figure-Payload). RetrieveEvidence() zieht
die autoritative typisierte Evidence GEZIELT aus der KB-Slice (top-20, in-scope) statt
sie im Breit-Basis-Text-Merge zu verlieren; /retrieve liefert footnotes[]/tables[]/
figures[]. Kein perColl-Blindanstieg. Dieselbe Infra trägt C8 (FIGURE) ohne Router-Umbau.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
6f0c1cf30d |
feat(ai-sdk): /retrieve liefert footnotes[] (C-FN Evidence) für Advisor-Workspace
Footnote-Hits werden aus dem Qdrant-Payload (is_footnote/footnote_label/ footnote_verbatim/ref_citation_unit) in interne LegalSearchResult-Felder (json:"-", kein Pro-Result-Contract-Change) gemappt und im /retrieve-Handler als Top-Level footnotes[] (Frontend RawFootnote-Shape) herausgezogen; Hits bleiben in results[] (LLM-Kontext). figures[] als leerer C8-Platzhalter. Speist den Evidence-Workspace (evidence-adapter.ts) der Frontend-Session. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
49171e841f |
feat(advisor): Evidence Workspace — structured panes, markdown, sources as knowledge units
Rebuilds the Compliance Advisor floating widget from a plain chat into an Evidence
Workspace: pinned last question, markdown-rendered answer (clean prose), and separate
panes for Sources (hierarchical Knowledge Units), Figures (C8, conditional) and
Footnotes (C-FN), plus a stats bar (Quellen/Regelwerke/Diagramme/Fußnoten). Scrollable
turn history; stays a floating icon on every SDK page.
Architecture (user direction): the frontend renders ONLY structured evidence and NEVER
parses the answer text. The proxy now returns a JSON AdvisorEvidenceMeta line followed
by the streamed markdown answer; advisor-rag exposes structured results; an adapter maps
RAG/compiler output to the frontend envelope. Figures/footnotes wire in once the
RAG-ingestion contract lands (requested on the board) — figures pane is conditional.
- lib/sdk/advisor/{evidence,evidence-adapter}.ts (+ adapter test, 7 cases)
- components/sdk/advisor/* panes + in-house safe Markdown (no new dep, no dangerouslySetInnerHTML) + test
- useAdvisorStream (meta-line parse + streamed answer) + useAdvisorEmail (escaped)
- proxy: evidence-meta-v1 envelope + clean-prose prompt (no inline citations)
- tsc clean, 11 vitest pass, check-loc 0. ESLint not installed in this node_modules -> CI lints on push.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
f0120b237e |
fix(ucca): Cross-Reg 0070 — beide Domaenen im Router-Top-K (#47)
CI / detect-changes (push) Successful in 6s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 9s
CI / validate-canonical-controls (push) Successful in 5s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Successful in 59s
CI / iace-gt-coverage (push) Successful in 18s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
1d65d99d5f |
style(ucca): gocritic equalFold in balanceByRegulation (go-lint gruen)
CI / detect-changes (pull_request) Successful in 14s
CI / branch-name (pull_request) Successful in 2s
CI / guardrail-integrity (pull_request) Successful in 6s
CI / secret-scan (pull_request) Successful in 6s
CI / dep-audit (pull_request) Failing after 54s
CI / sbom-scan (pull_request) Failing after 58s
CI / build-sha-integrity (pull_request) Successful in 5s
CI / validate-canonical-controls (pull_request) Successful in 4s
CI / loc-budget (pull_request) Successful in 20s
CI / go-lint (pull_request) Successful in 43s
CI / python-lint (pull_request) Failing after 18s
CI / nodejs-lint (pull_request) Failing after 1m10s
CI / nodejs-build (pull_request) Successful in 3m1s
CI / test-go (pull_request) Successful in 1m4s
CI / iace-gt-coverage (pull_request) Successful in 16s
CI / test-python-backend (pull_request) Successful in 27s
CI / test-python-document-crawler (pull_request) Successful in 12s
CI / test-python-dsms-gateway (pull_request) Successful in 13s
strings.EqualFold(code, cv) statt code==strings.ToUpper(cv) — behebt den einzigen gocritic-Befund auf der neuen Zeile (CI go-lint, new-from-merge-base). Verhalten unveraendert (case-insensitive exakter regulation_code-Match); Unit + 0070-e2e bleiben gruen. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
f2d445b891 |
fix(ucca): Cross-Reg 0070 — beide Regelwerk-Domaenen im Router-Top-K (Known Defects 0)
CI / detect-changes (pull_request) Successful in 13s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 9s
CI / secret-scan (pull_request) Successful in 10s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 59s
CI / build-sha-integrity (pull_request) Successful in 5s
CI / validate-canonical-controls (pull_request) Successful in 3s
CI / test-python-document-crawler (pull_request) Successful in 15s
CI / test-python-dsms-gateway (pull_request) Successful in 13s
CI / loc-budget (pull_request) Successful in 23s
CI / go-lint (pull_request) Failing after 51s
CI / python-lint (pull_request) Failing after 18s
CI / nodejs-lint (pull_request) Failing after 1m8s
CI / nodejs-build (pull_request) Successful in 3m6s
CI / test-go (pull_request) Successful in 1m3s
CI / iace-gt-coverage (pull_request) Successful in 18s
CI / test-python-backend (pull_request) Successful in 28s
Der einzige offene Retrieval-Haertefall: eine Query mit >=2 genannten Regelwerken
("CRA und Maschinenverordnung") lieferte nur die keyword-dominante Domaene (CRA),
MaschVO fiel raus. Drei zusammenwirkende Ursachen, alle behoben:
1. CodeValues-Mismatch: MaschVO heisst je Collection anders (Slice MASCHVO ·
gesetze MVO · ce MACHINERY/MASCHINENVO), der Catalog hatte nur ["MASCHVO","MaschVO"]
→ Filter fand MaschVO nur in der Slice. Jetzt alle Varianten als CodeValues.
2. Per-Collection-Truncation: der Router gab perColl=3 → searchMultiRegulation holte
3+3=6, schnitt auf 3 → konnte eine Domaene je Collection verlieren. Multi-Reg-Queries
bekommen jetzt perColl = 3*len(regs).
3. Router-Score-Merge starvte die nicht-dominante Domaene. Neue balanceByRegulation()
gruppiert den gemergten Pool per Regelwerk (exakter regulation_code-Match) und nimmt
round-robin ueber die genannten Domaenen → jede Domaene mit Treffern ist im Top-K.
Generisch ueber jede genannte Menge; Single-Domain-Pfad unveraendert.
Validierung: Go-Unit (balanceByRegulation: dominante CRA verdraengt MaschVO NICHT mehr);
0070-e2e gegen dev (Retrieve() → [CRA MVO CRA MVO CRA MVO CRA MASCHINENVO] = beide
Domaenen, vorher nur CRA); CB-100-Stichprobe REGR 0 (Gain-Profil unveraendert).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
08086ee75f |
feat: Authority Router — Advisor collection-agnostisch, KB-2026.1 live (#46)
CI / detect-changes (push) Successful in 6s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 5s
CI / validate-canonical-controls (push) Successful in 3s
CI / loc-budget (push) Successful in 17s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m58s
CI / test-go (push) Successful in 1m0s
CI / iace-gt-coverage (push) Successful in 15s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
1e5aaf7103 |
feat(advisor): Authority Router — Advisor collection-agnostisch, KB-2026.1-Gewinn im Produktpfad
CI / detect-changes (pull_request) Successful in 13s
CI / branch-name (pull_request) Successful in 2s
CI / guardrail-integrity (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 11s
CI / dep-audit (pull_request) Failing after 54s
CI / sbom-scan (pull_request) Failing after 1m1s
CI / build-sha-integrity (pull_request) Successful in 11s
CI / validate-canonical-controls (pull_request) Successful in 7s
CI / loc-budget (pull_request) Successful in 23s
CI / go-lint (pull_request) Successful in 53s
CI / python-lint (pull_request) Failing after 17s
CI / nodejs-lint (pull_request) Failing after 1m6s
CI / nodejs-build (pull_request) Successful in 2m59s
CI / test-go (pull_request) Successful in 1m0s
CI / iace-gt-coverage (pull_request) Successful in 17s
CI / test-python-backend (pull_request) Successful in 26s
CI / test-python-document-crawler (pull_request) Successful in 12s
CI / test-python-dsms-gateway (pull_request) Successful in 8s
Der Advisor fan-outete bisher selbst ueber eine feste Liste expliziter Collections
(advisor-rag.ts) und umging damit das #61-Scope-Routing (das nur den Default-Pfad
routet) → der gemessene +28-Retrieval-Gewinn (CB-100: 53→81, 0 Regr) kam nie beim
Antwort-LLM an. Dieser Router zieht den Fan-out in die Retriever-Schicht:
- SDK: LegalRAGClient.Retrieve() + POST /sdk/v1/rag/retrieve {query, top_k} —
fan-outet server-seitig ueber die Broad-Authority-Base + die KB-2026.1-Slice bei
inKBScope, merge+dedup, sortiert nach Authority-Score (rerankByAuthority je
Collection), top-K. Index-Warmup vor dem nebenlaeufigen Fan-out (Map-Race-frei).
Per-Env via RAG_ROUTER_COLLECTIONS.
- admin: advisor-rag.ts ruft EINMAL /retrieve statt 6-fach expliziter Collections.
Advisor ist collection-agnostisch (Vertrag Compiler→Collections→Retriever→Advisor);
COMPLIANCE_COLLECTIONS/searchCollection entfernt.
Validierung: Go-Unit (Router-Selektion, dedup); e2e gegen dev-Qdrant (echter
Retrieve(), CB-100-Stichprobe stride 5): OLD-hit 11/20 → NEW-hit 15/20, GAIN 4
(alle DS-Guidance), REGR 0 — reproduziert den +28/0-Regr durch den Produktionscode.
TS-Tests auf den Single-/retrieve-Call angepasst.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
af11d21f6e |
feat(ucca): Blue-Green KB-2026.1 Scope-Routing (authoritative slice) (#45)
CI / detect-changes (push) Successful in 5s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Successful in 59s
CI / build-sha-integrity (push) Successful in 4s
CI / validate-canonical-controls (push) Successful in 4s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / iace-gt-coverage (push) Successful in 15s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
e2c74fd243 |
feat(ucca): Blue-Green „authoritative slice promotion" — KB-2026.1 Scope-Routing
CI / detect-changes (pull_request) Successful in 12s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 9s
CI / secret-scan (pull_request) Successful in 10s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 1m1s
CI / build-sha-integrity (pull_request) Successful in 6s
CI / validate-canonical-controls (pull_request) Successful in 3s
CI / loc-budget (pull_request) Successful in 18s
CI / go-lint (pull_request) Successful in 52s
CI / python-lint (pull_request) Failing after 15s
CI / nodejs-lint (pull_request) Failing after 1m12s
CI / nodejs-build (pull_request) Successful in 3m4s
CI / test-go (pull_request) Successful in 1m2s
CI / iace-gt-coverage (pull_request) Successful in 19s
CI / test-python-backend (pull_request) Successful in 27s
CI / test-python-document-crawler (pull_request) Successful in 19s
CI / test-python-dsms-gateway (pull_request) Successful in 15s
Additiv (KEIN CE-Ersatz): faellt eine Query in den KB-2026.1-Scope (DP/CRA/MaschVO/ NIS2/DataAct/DORA/AIAct + EDPB/DSK-Guidance), wird die hochwertige Slice-Collection `kb_2026_1_build` abgefragt; sonst bleibt der breite Default `bp_compliance_ce`. Damit werden die Guidance-Intent- + Multi-Reg-Fixes (PR #42/#43) fuer den Slice LIVE, Broad-Corpus (OWASP/NIST/ENISA/IFRS/ISO) unangetastet -> 0 Regressionen by construction. - resolveCollection(query, requested): explizit angefragte Collection unveraendert; Default-Request -> Slice bei inKBScope, sonst CE. Env RAG_KB_SCOPE_ROUTING=false = Rollback ohne Redeploy; RAG_KB_SLICE_COLLECTION ueberschreibt den Slice-Namen. - inKBScope: detectRegulations (in-Slice-Regelwerke) + DP-Guidance-Marker (edpb/dsk/wp/gl) + DP/Compliance-Topics. Bewusst NICHT die generischen Verben aus guidanceIntentSignals (sagt/laut) und NICHT enisa/bsi/nist/owasp (die liegen in CE) -> konservativ, in-scope->Slice. Validierung: Unit (Scoping + resolveCollection); dev-e2e (RUN_E2E, geroutetes Search() gegen dev): WP248/MaschVO/CRA+MaschVO -> Slice (Treffer da, fehlen in dev-ce); NIST -> CE (NIST-Treffer). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
8ed99c255d |
Merge pull request 'fix(api): F821-Regression (Extract-Service-Halb-Refactor) — 7 Route-Dateien' (#44) from fix/api-f821-extract-service-regression into main
CI / detect-changes (push) Successful in 8s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 9s
CI / validate-canonical-controls (push) Successful in 7s
CI / loc-budget (push) Successful in 22s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 27s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
3389fa3e7a |
fix(api): F821-Regression in 6 weiteren Route-Dateien beheben
CI / detect-changes (pull_request) Successful in 5s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 8s
CI / dep-audit (pull_request) Failing after 57s
CI / sbom-scan (pull_request) Failing after 56s
CI / build-sha-integrity (pull_request) Successful in 6s
CI / validate-canonical-controls (pull_request) Successful in 5s
CI / loc-budget (pull_request) Successful in 22s
CI / go-lint (pull_request) Successful in 46s
CI / python-lint (pull_request) Failing after 17s
CI / nodejs-lint (pull_request) Failing after 1m8s
CI / nodejs-build (pull_request) Successful in 3m1s
CI / test-go (pull_request) Successful in 1m2s
CI / iace-gt-coverage (pull_request) Successful in 18s
CI / test-python-backend (pull_request) Successful in 25s
CI / test-python-document-crawler (pull_request) Successful in 14s
CI / test-python-dsms-gateway (pull_request) Successful in 10s
Gleiche Wurzel wie evidence_routes (Extract-Service-Refactor
|
||
|
|
79abf23ea8 |
fix(api): evidence_routes F821-Regression beheben (Extract-Service-Halb-Refactor)
|
||
|
|
d5925e57af |
feat(ai-sdk): pin accepted proposer decisions into the GT gate (P3)
CI / detect-changes (push) Successful in 12s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 9s
CI / validate-canonical-controls (push) Successful in 8s
CI / loc-budget (push) Successful in 21s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Successful in 59s
CI / iace-gt-coverage (push) Successful in 19s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
When a human accepts a proposer proposal, an AcceptedPin records a machine-scoped invariant — a pattern MUST fire (coverage/vocab→tag) or must NOT fire (dedup/framing) — that a test re-checks on every run. This makes the library's growth COMPOUND into the gate instead of eroding it: a change that re-introduces a dropped duplicate, un-gates a foreign pattern, or removes a coverage hazard breaks a pin and fails CI. One boolean covers all four proposal types. Seeded testdata/accepted_pins_warewashing.json with the accepted P1 supersessions (HP016/HP018/HP013 must NOT fire; their clean equivalents HP2201/HP144 must fire). TestWarewashing_AcceptedPins re-checks 5/5 against the live engine output; GenerateDedupPin turns an accepted dedup verdict into its pin. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
1877829b1d |
Merge remote-tracking branch 'gitea/main' into reconcile-dev
CI / detect-changes (push) Successful in 10s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 8s
CI / validate-canonical-controls (push) Successful in 5s
CI / loc-budget (push) Successful in 22s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 3m3s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 26s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
866889b453 |
Merge pull request 'feat(ucca): Multi-Regulation-Retrieval (Cross-Regulation-Fragen)' (#43) from fix/multi-regulation-retrieval into main
CI / detect-changes (push) Successful in 12s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 7s
CI / validate-canonical-controls (push) Successful in 6s
CI / loc-budget (push) Successful in 21s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Successful in 1m0s
CI / iace-gt-coverage (push) Successful in 20s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
9760dca443 |
feat(ucca): Multi-Regulation-Retrieval für Cross-Regulation-Fragen
CI / detect-changes (pull_request) Successful in 10s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 8s
CI / secret-scan (pull_request) Successful in 9s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 58s
CI / build-sha-integrity (pull_request) Successful in 9s
CI / validate-canonical-controls (pull_request) Successful in 7s
CI / loc-budget (pull_request) Successful in 24s
CI / go-lint (pull_request) Successful in 54s
CI / python-lint (pull_request) Failing after 16s
CI / nodejs-lint (pull_request) Failing after 1m9s
CI / nodejs-build (pull_request) Successful in 3m6s
CI / test-go (pull_request) Successful in 1m3s
CI / iace-gt-coverage (pull_request) Successful in 19s
CI / test-python-backend (pull_request) Successful in 26s
CI / test-python-document-crawler (pull_request) Successful in 15s
CI / test-python-dsms-gateway (pull_request) Successful in 12s
Nennt eine Query EXPLIZIT >=2 Regelwerke ("Wie greifen CRA und Maschinen-
verordnung ineinander?"), retrievt searchInternal pro Regelwerk separat
(regulation_code/regulation_id-Filter) und merged — damit BEIDE Domänen im
Prompt landen statt nur der keyword-dominanten. Generisch (Query->Regelwerke,
KEINE doc-spezifische Logik), gegated auf >=2 erkannte Regelwerke; sonst
unveränderter Single-Domain-Pfad.
Behebt GQ-0070: vorher CRA x8 / null MaschVO -> Modell halluzinierte
MaschVO=2019/2144 + falsche "CRA ausgenommen"-Konklusion. Nachher CRA + MaschVO
im Prompt -> korrekt "beide gleichzeitig anwendbar" + Art. 20(9)
Konformitätsvermutung, gegroundet.
Validierung (Build-Collection, echtes SearchCollection):
- Unit: detectRegulations-Scoping (>=2 -> multi, 1/0 -> single)
- 5 Cross-Reg-Fälle (0070 + DSGVO+TDDDG/CRA+NIS2/DORA+NIS2/AI Act+DSGVO):
beide Regelwerke in Top-8
- CB-100 Freeze-Regression: NUR GQ-0070 + GQ-0095 geändert (beide echte
Cross-Reg, beide verbessert), 98/100 byte-identisch
- 10 Hard Cases: 9 Single-Domain unverändert, 0070 behält CRA Rang 1
Filter erweitert auf regulation_id UND regulation_code (rückwärtskompatibel,
aktiviert die re-ingestierte Build-Collection).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
e5e7b825af |
Merge pull request 'fix(ucca): Guidance-Intent für direkt benannte WP/GL-Dokumente' (#42) from fix/legal-rag-guidance-intent into main
CI / branch-name (push) Has been skipped
CI / detect-changes (push) Successful in 7s
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 6s
CI / validate-canonical-controls (push) Successful in 5s
CI / loc-budget (push) Successful in 20s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Successful in 1m0s
CI / iace-gt-coverage (push) Successful in 17s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
4818fc51c2 |
fix(ucca): guidance-intent erkennt direkt benannte Guidance-Dokumente
CI / detect-changes (pull_request) Successful in 7s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 5s
CI / secret-scan (pull_request) Successful in 9s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 58s
CI / build-sha-integrity (pull_request) Successful in 7s
CI / validate-canonical-controls (pull_request) Successful in 7s
CI / loc-budget (pull_request) Successful in 21s
CI / go-lint (pull_request) Successful in 48s
CI / python-lint (pull_request) Failing after 17s
CI / nodejs-lint (pull_request) Failing after 1m9s
CI / nodejs-build (pull_request) Successful in 3m2s
CI / test-go (pull_request) Successful in 1m3s
CI / iace-gt-coverage (pull_request) Successful in 18s
CI / test-python-backend (pull_request) Successful in 28s
CI / test-python-document-crawler (pull_request) Successful in 14s
CI / test-python-dsms-gateway (pull_request) Successful in 11s
queryWantsGuidance verfehlte rein dokument-namige Fragen ("Welche Kriterien
nennt WP248 ...", "Was sagt GL 07/2020 ..."): guidanceIntentSignals enthielt
zwar Herausgeber (edpb/dsk/enisa) und Verben (empfiehlt/laut), aber keine
Working-Paper-/Guideline-Identifier. Dadurch loeste der Authority-Lift nicht
aus -> binding_law (bzw. im homogenen Korpus sogar off-domain MaschVO/CRA)
verdraengte die Guidance aus den Top-K.
Fix: WP2xx / GL 0x / "working paper" als Guidance-Signal ergaenzt. Generisch
ueber alle WP-/GL-Dokumente, KEINE doc-spezifische Regel (Query->Intent, nicht
Query->konkretes Dokument).
Validierung (homogener Build-Korpus, bge-m3 + Qdrant Cosine):
- 10 Hard Cases: 8/10 -> 10/10 (WP248/WP260 zurueck in Top-8)
- ComplianceBench-100: 0/100 Norm-Fragen veraendert (Freeze-Regression gruen),
18/18 Guidance-Intent-Fragen verbessert (binding -> korrekte Guidance-Klasse)
- Hybrid == Dense (Keyword-RRF war NICHT die Ursache, der Lift-Gate war es)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
f0da86ca19 | Merge pull request 'feat(onboarding): advisor responsiveness — moving headline + auto-recompute' (#54) from feat/advisor-ux-responsiveness into main | ||
|
|
867f8c3854 |
feat(onboarding): make the advisor visibly responsive — headline leads with the moving number + auto-recompute
Testing surfaced that toggling certifications appeared to "do nothing": the headline led with the TOTAL
requirement count (constant per target, e.g. 17 for CRA), and the page only recomputed on an explicit
button click. Both fixed:
- engine.py headline now leads with the number that actually moves: "11 von 17 Anforderungen offen ·
6 wahrscheinlich (Zertifikate) · 5 zu klären" (was "17 Anforderungen erkannt · …"). Keeps the
"automatisch erkannt (Intake)" substring.
- frontend auto-recomputes on certifications / target / scanner-signal change (no button needed).
Now ISO27001 alone -> "13 von 17 offen · 4 wahrscheinlich"; + ISO9001+TISAX+IEC62443 -> "11 von 17 offen ·
6 wahrscheinlich". (Domain truth stays visible: CRA's product-cyber gaps barely move with management-system
certs.) 28 onboarding+transition tests pass, check-loc 0.
|
||
|
|
26a8518107 | Merge pull request 'feat(onboarding): surface curated expert text + human labels' (#53) from feat/advisor-human-text into main | ||
|
|
807a7002b2 |
feat(onboarding): surface curated expert text + human capability labels (advisor was showing snake_case)
The advisor was structurally correct but unusable: every question showed a snake_case capability id plus a
single generic fallback reason ("Keine Anhaltspunkte im Unternehmensprofil — klären"). The expert text
already EXISTED in the transition patterns (why_asked / reviewable_claim) — the pipeline just dropped it.
- transition_reasoning: TargetRequirement gains `rationale`; assess_transition uses it as the request
reason when present, else the generic fallback (additive, backward-compatible for all consumers).
- onboarding_service._target carries the pattern's why_asked (delta) and reviewable_claim (likely_covered)
into the requirement rationale -> the question's `why`.
- knowledge/onboarding/capability_labels.yaml: curated DE labels (id -> human), reusable across targets;
labels_for() + response.capability_labels expose them; the frontend renders label || prettified id.
Now ISO27001->TISAX reads "Auftragsverarbeitung (Art. 28 DSGVO) — If a TISAX data label is in scope, you
must show Art. 28 GDPR processing-on-behalf controls; ISO 27001 does not establish these." instead of
"data_protection_processing_on_behalf — klären". why_asked text is still EN (existing knowledge; translation
is curation). 34 onboarding+transition tests pass, mypy --strict clean (13 modules), check-loc 0.
|
||
|
|
5beb5a319a | Merge pull request 'feat(admin): ETO / Onboarding-Advisor test page' (#52) from feat/onboarding-advisor-frontend into main | ||
|
|
239702fdca |
feat(admin): ETO / Onboarding-Advisor test page (thin operator surface over the advisor endpoint)
A focused client page at /sdk/onboarding-advisor that exercises POST /api/compliance/onboarding/ advisor-start through the existing compliance proxy: pick certifications + target + scanner findings (observation / partial / requirement) and render the result — headline, silent-intake summary, auto-detected (green), indications (amber), next-best questions with WHY, inferred (Welt-1) vs rejected assumptions, capability delta, evidence requests, completeness. NOT the regulation gap engine (/sdk/gap-analysis is a different flow). No new backend; calls only the existing endpoint. 195 lines. |
||
|
|
d1a5fc7205 | Merge pull request 'feat(onboarding): Observation Log — append-only JSONL calibration store (59b/c)' (#51) from feat/observation-log into main | ||
|
|
7df15010ff |
feat(onboarding): Observation Log — append-only JSONL calibration store (Task 59b/c v1)
Per the user's decision (2026-06-28): observations are CALIBRATION data for the knowledge base, NOT
business data and NOT product-DB data. So they live with the other versioned knowledge artifacts as an
append-only JSONL log under knowledge/observations/ — NO migration, NO DB. (A real persistence layer is
only warranted once thousands of onboardings exist; not before.)
- ObservationRecord = Observation + log metadata (observation_id, timestamp [caller-stamped, no hidden
clock], customer_archetype [anonymised — NEVER a real name], evidence, provenance, knowledge_version).
- append_observation() writes one JSON line; append-only, lines are never rewritten. A later review is a
NEW line with the same observation_id; load_observations(reconcile=True) keeps the latest per id.
- load_observations() reads a single .jsonl or a directory of monthly .jsonl files.
- aggregate_by_hypothesis() (59c) -> per-hypothesis distribution + confidence, COMPUTED from the log
(computed-not-stored); the review gate (reviewed-only) is enforced in empirical_distribution/confidence.
- review_queue() -> the unreviewed worklist. Observation -> Review -> Accepted -> recompute, never
Observation -> confidence++. Nothing is ever written back to a hypothesis.
You can `rm` the log and recompute, `git diff` it over months, or rebuild confidence under a new policy —
fully consistent with computed-not-stored and the product/knowledge data separation.
Non-runtime (module + tests only, no endpoint) -> origin/main, NO dev deploy. 5 new tests (append-only,
review supersession, review-gate statistics, queue, monthly-file load); 27 onboarding tests pass, mypy
--strict clean (9 modules), check-loc 0. 59d (surface computed confidence at runtime) stays a later step.
|
||
|
|
e54f3cde94 |
Merge pull request 'fix(onboarding): review decisions — ISO13485 + patch rationale + summary counter' (#50) from feat/review-decisions into main
CI / detect-changes (push) Successful in 5s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 4s
CI / validate-canonical-controls (push) Successful in 3s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 23s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
77459d06d6 |
fix(onboarding): apply hypothesis/vocabulary review decisions (ISO13485, patch-policy rationale, summary)
Two reviewed knowledge decisions (2026-06-28) + the deferred cosmetic counter, before #59. 1. ISO13485 removed from the incident_management hypothesis. ISO 13485 CAPA / quality-safety incident handling is NOT security incident management — the mapping was too broad and would seed false hypotheses for the empirical loop. A dedicated manage_quality_and_safety_incidents capability can come later IF a target needs it; not forced now. (ISO27001/TISAX/IEC62443 keep incident_management.) 2. patch_policy_doc -> secure_signed_update_distribution stays `partial`, but the curated rationale is sharpened: "indicates update governance, does not evidence signed distribution" (a patch policy is not proof of SIGNED distribution). New optional SignalMapping.rationale field carries the curated note. (github_actions_ci -> SDL and dependency_scanning -> vuln-mgmt reviewed and APPROVED as-is.) 3. Cosmetic (folded in since we touched the file): the silent-intake summary now counts detected and indications SEPARATELY ("N automatisch erkannt, M Indikation(en)") instead of lumping partial signals into "automatisch erkannt" — consistent with the three-state model just shipped. Tests: ISO13485 no longer resolves to incident_management; summary counts split correctly. 29 onboarding tests pass, mypy --strict clean, demo runs, check-loc 0. Runtime-visible (hypothesis resolution + summary text) -> deploy + smoke. |
||
|
|
3202e555ab |
Merge pull request 'fix(onboarding): partial != detected — indication, not auto-detect (Fix B)' (#49) from feat/partial-decouple into main
CI / detect-changes (push) Successful in 5s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 5s
CI / validate-canonical-controls (push) Successful in 3s
CI / loc-budget (push) Successful in 18s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 23s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
|
||
|
|
978052b5a2 |
fix(onboarding): decouple partial/indicative signals from detected — partial no longer removes a question
Fix B of the pre-#59 semantic correction. The Silent Pass had only TWO effective states though the data
carries three: a `detected` mapping (a concrete artifact) AND a `partial` mapping (an indicative signal,
e.g. a CI pipeline -> secure-development-lifecycle) both flowed through capability_ids() and were fed to
the Advisor as already-present — so a weak indication silently removed a question, exactly the Welt-1/
Welt-2 transparency we want to keep.
Now three distinct states:
- detected -> reduces the delta immediately (auto_detected, not asked). [unchanged]
- partial -> raises assumption strength but does NOT replace the question (surfaced as `indications`,
the capability stays in the delta and is still asked).
- requirement-> describes a target, never the present state (already handled by Fix A's kind split).
Changes (data + thin wiring, no new architecture):
- SilentIntakeResult.capability_ids() returns only relationship==detected; new indicative_capability_ids()
returns the partial ones.
- advisor_start() gains indicative_capabilities (NOT fed into the profile) and surfaces result.indications
= indicative ∩ required − auto_detected.
- AdvisorResult / AdvisorResponse gain `indications` (additive, contract-safe); the service passes the
indicative ids through.
Tests: a partial CI signal is indicative-not-detected and does NOT shrink the delta; end-to-end it appears
in `indications`, not `auto_detected`, and the gap is still asked. 28 onboarding tests pass, mypy --strict
clean on the onboarding modules, demo runs, check-loc 0. Runtime effect -> deploy + smoke.
|