package intent import ( "context" "errors" "os" "path/filepath" "strings" "testing" _ "modernc.org/sqlite" "github.com/tegwick/fluid-core/internal/contract" "github.com/tegwick/fluid-core/internal/evidence" ) func newStore(t *testing.T) *Store { t.Helper() ev, err := evidence.OpenSQLite(context.Background(), filepath.Join(t.TempDir(), "e.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = ev.Close() }) return New(ev, "hall-publishing") } const filledIntent = `# Interface Evolution Intent **Current operational authority mode:** FLUID-2 ## Mission Publish hall-of-helix entries to a Telegram channel. ` func TestPutIsIdempotentAndImmutable(t *testing.T) { s := newStore(t) ctx := context.Background() first, err := s.Put(ctx, "IEI-1", filledIntent) if err != nil { t.Fatal(err) } if first.Mode != ModeAdvisory { t.Errorf("mode = %s, want FLUID-2", first.Mode) } // Recording the same content again must be a no-op, so startup is safe to // repeat. again, err := s.Put(ctx, "IEI-1", filledIntent) if err != nil { t.Fatalf("re-recording identical intent failed: %v", err) } if again.Digest != first.Digest { t.Error("identical documents produced different digests") } // Changing what a version says, after revisions may already be bound to it, // would break the audit question the store exists to answer. changed := strings.Replace(filledIntent, "FLUID-2", "FLUID-5", 1) if _, err := s.Put(ctx, "IEI-1", changed); !errors.Is(err, ErrImmutable) { t.Errorf("mutating a recorded version returned %v, want ErrImmutable", err) } } func TestParseModeRejectsUnresolvedTemplate(t *testing.T) { // The shipped template lists every mode as alternatives. Accepting that and // defaulting to something permissive is exactly the wrong failure. template, err := os.ReadFile(filepath.Join("..", "..", "spec", "InterfaceEvolutionIntent.md")) if err != nil { t.Skipf("template not readable: %v", err) } if _, err := ParseMode(string(template)); err == nil { t.Error("the unfilled template was accepted as a governing intent") } if _, err := ParseMode("no mode declared here"); err == nil { t.Error("a document with no authority mode was accepted") } } func TestAuthorityModeOrdering(t *testing.T) { if !ModeExperimental.Allows(ModeAdvisory) { t.Error("FLUID-4 should permit advisory authority") } if ModeAdvisory.Allows(ModeExperimental) { t.Error("FLUID-2 must not permit experimental authority") } if got := ModeBoundedAutonomous.String(); got != "FLUID-5" { t.Errorf("String() = %s", got) } } func TestActiveIntent(t *testing.T) { s := newStore(t) ctx := context.Background() if _, err := s.Active(ctx); !errors.Is(err, ErrNoActive) { t.Errorf("Active with nothing recorded returned %v, want ErrNoActive", err) } if _, err := s.Put(ctx, "IEI-1", filledIntent); err != nil { t.Fatal(err) } if err := s.SetActive(ctx, "IEI-1"); err != nil { t.Fatal(err) } active, err := s.Active(ctx) if err != nil { t.Fatal(err) } if active.Version != "IEI-1" { t.Errorf("active = %s, want IEI-1", active.Version) } if err := s.SetActive(ctx, "IEI-missing"); err == nil { t.Error("activating an unrecorded version succeeded") } } func TestBindingIsRecordedAndFirstWins(t *testing.T) { s := newStore(t) ctx := context.Background() if _, err := s.Put(ctx, "IEI-1", filledIntent); err != nil { t.Fatal(err) } v2 := strings.Replace(filledIntent, "FLUID-2", "FLUID-4", 1) if _, err := s.Put(ctx, "IEI-2", v2); err != nil { t.Fatal(err) } rev := contract.RevisionID("R-1") if err := s.Bind(ctx, rev, "IEI-1"); err != nil { t.Fatal(err) } got, err := s.GoverningIntent(ctx, rev) if err != nil { t.Fatal(err) } if got.Version != "IEI-1" { t.Errorf("governing intent = %s, want IEI-1", got.Version) } // A later reassignment is recorded in the audit trail but must not silently // become the answer to "what governed this revision". if err := s.Bind(ctx, rev, "IEI-2"); err != nil { t.Fatal(err) } got, err = s.GoverningIntent(ctx, rev) if err != nil { t.Fatal(err) } if got.Version != "IEI-1" { t.Errorf("a later binding overrode the original: got %s", got.Version) } } func TestUnboundRevisionHasNoIntent(t *testing.T) { s := newStore(t) if _, err := s.GoverningIntent(context.Background(), "R-unbound"); !errors.Is(err, ErrNotFound) { t.Errorf("got %v, want ErrNotFound", err) } }