package main
import (
"path/filepath"
"strings"
"testing"
"time"
"craftdesign.group/quarry/internal/artifact"
"craftdesign.group/quarry/internal/index"
)
func foldTrunk(t *testing.T, ix *index.Index, hash, date, user string, parents ...string) {
t.Helper()
art := &artifact.Artifact{Type: artifact.Manifest, Date: date, User: user, Comment: "c " + hash[:4], Parents: parents}
if len(parents) == 0 {
art.Tags = []artifact.Tag{{Name: "*branch", Target: "*", Value: "trunk"}}
}
if err := ix.FoldNow([]index.Parsed{{Hash: hash, Art: art}}); err != nil {
t.Fatal(err)
}
}
// THE FORGE'S OWN ACCEPT IS NOT A BYPASS.
//
// An accept writes its merge, the fold makes it visible, and the gate
// sweep runs on that fold; the accept recorded "this merge was mine"
// only after closing the landing's tickets. A sweep in that gap flagged
// dmestas's accepts on the CI page as "committed straight to trunk".
// A finding now waits a grace from first sight, and one the forge
// records in that time is never flagged; a real push past the gate
// still is, once the grace is up.
func TestTheGateWaitsForTheForgesOwnAccept(t *testing.T) {
ix, err := index.Open(filepath.Join(t.TempDir(), "index.db"))
if err != nil {
t.Fatal(err)
}
defer ix.Close()
rg := newTestRegistrar(t, 25)
if err := rg.odb.SetProtection("r", "trunk", []string{"dmestas"}); err != nil {
t.Fatal(err)
}
now := time.Date(2026, 9, 23, 22, 0, 0, 0, time.UTC)
rg.clock = func() time.Time { return now }
rg.gateGrace = time.Minute
h := func(c string) string { return strings.Repeat(c, 64) }
bypasses := func() int {
bs, err := rg.odb.GateBypasses("r", 0)
if err != nil {
t.Fatal(err)
}
return len(bs)
}
foldTrunk(t, ix, h("0"), "2026-09-23T21:00:00", "dmestas")
rg.gateSweep("r", ix) // first sight: baseline, nothing flagged
// The forge's merge is folded before its accept is recorded.
foldTrunk(t, ix, h("1"), "2026-09-23T22:00:00", "dmestas", h("0"))
rg.gateSweep("r", ix)
if n := bypasses(); n != 0 {
t.Fatalf("FAIL: the forge's own merge was flagged in the gap before its accept was recorded (%d)", n)
}
if err := rg.odb.RecordForgeAccept("r", h("1")); err != nil {
t.Fatal(err)
}
now = now.Add(2 * time.Minute)
rg.gateSweep("r", ix)
if n := bypasses(); n != 0 {
t.Fatalf("FAIL: a merge the forge accepted was flagged (%d)", n)
}
// A push past the gate is still caught, once the grace is up.
foldTrunk(t, ix, h("2"), "2026-09-23T22:03:00", "mallory", h("1"))
rg.gateSweep("r", ix)
if n := bypasses(); n != 0 {
t.Fatalf("FAIL: flagged inside the grace (%d)", n)
}
now = now.Add(61 * time.Second)
rg.gateSweep("r", ix)
if n := bypasses(); n != 1 {
t.Fatalf("FAIL: a push nobody accepted was not flagged after the grace (%d findings)", n)
}
}