access-engine/internal/decision/emission_release_test.go
tegwick 22185e94ec Withhold uncommitted decision effects and pin accepted layer canon
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 02:21:40 +02:00

51 lines
1.6 KiB
Go

package decision
import (
"errors"
"testing"
"github.com/netkingdom/access-engine/pkg/api"
)
type commitProbe struct {
fail bool
committed []api.DecisionEnvelope
released int
}
func (p *commitProbe) Append(d api.DecisionEnvelope) error {
if p.fail {
return errors.New("disk unavailable")
}
p.committed = append(p.committed, d)
return nil
}
func (p *commitProbe) NoteReleasedUncommitted(api.DecisionEffect) { p.released++ }
// Every source-owned emission class is load-bearing. An outbox failure must
// hide every effect from both the response and Explain, including restrictions.
func TestRequiredCommitForEveryEffect(t *testing.T) {
for _, effect := range api.DecisionEffects() {
t.Run(string(effect), func(t *testing.T) {
probe := &commitProbe{fail: true}
engine := &Engine{history: make(map[string]api.DecisionEnvelope), log: probe}
d := api.DecisionEnvelope{ID: "decision", Effect: effect}
if err := engine.recordDecisions([]api.DecisionEnvelope{d}); !errors.Is(err, ErrRecordNotCommitted) {
t.Fatalf("commit failure = %v; want unavailable", err)
}
if _, err := engine.Explain(d.ID); err == nil {
t.Fatal("uncommitted decision exposed by Explain")
}
if probe.released != 0 || len(probe.committed) != 0 {
t.Fatal("failed commit claimed a release")
}
probe.fail = false
if err := engine.recordDecisions([]api.DecisionEnvelope{d}); err != nil {
t.Fatal(err)
}
if got, err := engine.Explain(d.ID); err != nil || got.Effect != effect {
t.Fatalf("committed explanation = %+v, %v", got, err)
}
})
}
}