feat(ai-sdk): runnable iace-audit propose CLI + live LLM wiring (P2 slice 3)
Makes the offline proposer runnable end-to-end.
- BuildProposerInput (proposer_input.go): non-test engine->hazards path. The
PatternMatch->Hazard converter is lifted out of the GT test files into
production scope so both the tests and the CLI share one pipeline.
- iace-audit propose <narrative.json> [<ground-truth.json>]: detect candidates ->
GT-screen survivors (when a ground truth is given) -> judge (HeuristicJudge by
default, LLMJudge over ollama when IACE_PROPOSE_LLM=1) -> write the human-review
queue to audit-reports/proposals.{md,json}. Propose-only.
Smoke run on a dishwasher narrative: 32 fired -> 3 candidates -> queue with a
confident duplicate, a confident distinct, and one punted to the LLM judge; GT
wall recall-safe. Live qwen is opt-in via env; the heuristic default keeps the
tool runnable (and CI deterministic) without a model. Proposal types 2-4
(foreign-framing gates, vocab->tag, coverage blind spots) remain for slice 4.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package iace
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestBuildProposerInput_WarewashingFires(t *testing.T) {
|
||||
hazards, _, fired := BuildProposerInput(
|
||||
warewashingNarrative,
|
||||
"Gewerbliche Untertisch-Geschirrspuelmaschine (vernetzt)",
|
||||
[]string{"food_processing"},
|
||||
)
|
||||
if len(fired) == 0 || len(hazards) == 0 {
|
||||
t.Fatalf("want fired patterns + hazards, got %d patterns / %d hazards", len(fired), len(hazards))
|
||||
}
|
||||
has := func(id string) bool {
|
||||
for _, pm := range fired {
|
||||
if pm.PatternID == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if !has("HP2201") {
|
||||
t.Errorf("warewashing-specific HP2201 must fire via BuildProposerInput")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user