返回 DeepSeek-Reasonix
costquote_capability_test.go
根目录 / internal / event / costquote_capability_test.go
1 package event
2
3 import (
4 "testing"
5
6 "reasonix/internal/evidence"
7 )
8
9 // capabilityRecorder accepts every optional sink capability and names the ones
10 // it received.
11 type capabilityRecorder struct {
12 got map[string]bool
13 }
14
15 func newCapabilityRecorder() *capabilityRecorder {
16 return &capabilityRecorder{got: map[string]bool{}}
17 }
18
19 func (c *capabilityRecorder) mark(name string) { c.got[name] = true }
20 func (c *capabilityRecorder) Emit(Event) { c.mark("emit") }
21 func (c *capabilityRecorder) RecordTurnCompletion() { c.mark("turn_completion") }
22
23 func (c *capabilityRecorder) RecordReadinessAudit(evidence.ReadinessAudit) {
24 c.mark("readiness_audit")
25 }
26 func (c *capabilityRecorder) RecordAnchorSafetyAudit(AnchorSafetyAudit) {
27 c.mark("anchor_safety_audit")
28 }
29 func (c *capabilityRecorder) RecordContractShadow(ContractShadowAudit) { c.mark("contract_shadow") }
30 func (c *capabilityRecorder) RecordCompletionReport(CompletionReportAudit) {
31 c.mark("completion_report")
32 }
33 func (c *capabilityRecorder) RecordMemoryRecall(MemoryRecallAudit) { c.mark("memory_recall") }
34 func (c *capabilityRecorder) RecordDelegationAdmission(DelegationAdmissionAudit) {
35 c.mark("delegation_admission")
36 }
37 func (c *capabilityRecorder) RecordOutcomeProgress(evidence.OutcomeSample) {
38 c.mark("outcome_progress")
39 }
40 func (c *capabilityRecorder) RecordProtocolRecovery(ProtocolRecoveryAudit) {
41 c.mark("protocol_recovery")
42 }
43 func (c *capabilityRecorder) RecordDelegationAudit(evidence.DelegationAudit) {
44 c.mark("delegation_audit")
45 }
46 func (c *capabilityRecorder) RecordWorkspaceMutation(WorkspaceMutation) {
47 c.mark("workspace_mutation")
48 }
49 func (c *capabilityRecorder) RecordRunBudget(RunBudgetSample) { c.mark("run_budget") }
50
51 // A wrapper that drops an optional capability silently truncates every recorder
52 // below it: the trajectory and stats recorders sit under the quoting sink, so
53 // this one dropping them meant real runs recorded no audits at all while every
54 // unit test — which wires recorders directly — stayed green.
55 func TestCostQuoteSinkPreservesEveryAuditCapability(t *testing.T) {
56 inner := newCapabilityRecorder()
57 // Sink, not *CostQuoteSink: the host reaches these channels through the
58 // package dispatchers, which type-assert and silently no-op on a wrapper
59 // that lost the capability. Calling the methods directly instead would turn
60 // this guard into a compile error that only fires when they vanish outright.
61 var s Sink = NewCostQuoteSink(inner, nil)
62
63 s.Emit(Event{Kind: Notice})
64 RecordTurnCompletion(s)
65 RecordReadinessAudit(s, evidence.ReadinessAudit{})
66 RecordAnchorSafetyAudit(s, AnchorSafetyAudit{Mode: "shadow"})
67 RecordContractShadow(s, ContractShadowAudit{})
68 RecordCompletionReport(s, CompletionReportAudit{})
69 RecordMemoryRecall(s, MemoryRecallAudit{})
70 RecordDelegationAdmission(s, DelegationAdmissionAudit{})
71 RecordOutcomeProgress(s, evidence.OutcomeSample{Round: 1})
72 RecordProtocolRecovery(s, ProtocolRecoveryAudit{})
73 RecordDelegationAudit(s, evidence.DelegationAudit{})
74 RecordWorkspaceMutation(s, WorkspaceMutation{})
75 RecordRunBudget(s, RunBudgetSample{})
76
77 for _, want := range []string{
78 "emit", "turn_completion", "readiness_audit", "anchor_safety_audit", "contract_shadow",
79 "completion_report", "memory_recall", "delegation_admission",
80 "outcome_progress", "protocol_recovery", "delegation_audit",
81 "workspace_mutation", "run_budget",
82 } {
83 if !inner.got[want] {
84 t.Errorf("quoting sink swallowed %s; everything recorded below it loses that channel", want)
85 }
86 }
87 }
88
88 lines GO