445079cfb2
Quote-verifiable failure extraction via Claude (Haiku 4.5): PDF sent directly, tool-schema forces verbatim source quotes + applicable flag + confidence — replaces the unreliable local llama run. Only applicable=true tuples ingest into bp_iace_failure_kb; every processed doc lands in the source manifest. Frontend: FMEA tab now shows a "Quelldokumente" register (every document we use, with source + licence + link + what was extracted) served from the embedded manifest via GET /iace/failure-knowledge/sources. Manifest is placeholder until the 100-doc Haiku run is folded in. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
70 lines
2.3 KiB
Go
70 lines
2.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ListFailureKnowledge handles GET /failure-knowledge.
|
|
// Read-only unified failure-knowledge ontology (Component → FailureMode →
|
|
// Mechanism → Effect → Hazard → Harm → Control) curated from commercially-usable
|
|
// open sources (currently NASA NTRS, public domain). Optional ?domain= filter.
|
|
// This is the shared corpus that seeds the FMEA library and the CE hazard side.
|
|
func (h *IACEHandler) ListFailureKnowledge(c *gin.Context) {
|
|
var items []iace.FailureKnowledge
|
|
if d := c.Query("domain"); d != "" {
|
|
items = iace.FailureKnowledgeByDomain(d)
|
|
} else {
|
|
items = iace.AllFailureKnowledge()
|
|
}
|
|
if items == nil {
|
|
items = []iace.FailureKnowledge{}
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"failure_knowledge": items,
|
|
"total": len(items),
|
|
})
|
|
}
|
|
|
|
// ListFailureSources handles GET /failure-knowledge/sources.
|
|
// The source-document register for the FMEA frontend: EVERY document we use,
|
|
// with its source + licence + URL (and what was extracted). Always visible so an
|
|
// auditor sees the full provenance of the failure-knowledge corpus.
|
|
func (h *IACEHandler) ListFailureSources(c *gin.Context) {
|
|
c.JSON(http.StatusOK, iace.GetFailureSources())
|
|
}
|
|
|
|
// HarvestNTRSFailures handles GET /failure-knowledge/ntrs.
|
|
// Live-harvests NASA NTRS lessons-learned metadata and returns only the records
|
|
// that pass the public-reuse licence gate (Stage 1 of the bulk loader). Tuple
|
|
// extraction from the abstracts is a downstream step.
|
|
func (h *IACEHandler) HarvestNTRSFailures(c *gin.Context) {
|
|
q := c.DefaultQuery("q", "lessons learned failure")
|
|
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "25"))
|
|
lessons, err := iace.FetchNTRSLessons(c.Request.Context(), q, limit)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
out := []gin.H{}
|
|
skipped := 0
|
|
for _, l := range lessons {
|
|
ok, lic := iace.NTRSUsable(l)
|
|
if !ok {
|
|
skipped++
|
|
continue
|
|
}
|
|
out = append(out, gin.H{
|
|
"id": l.ID, "title": l.Title, "abstract": l.Abstract,
|
|
"license": lic, "pdf_url": iace.NTRSPDFURL(l), "is_lessons_learned": l.IsLessonsLearned,
|
|
})
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"query": q, "usable": out, "usable_count": len(out),
|
|
"skipped_non_open": skipped, "total_fetched": len(lessons),
|
|
})
|
|
}
|