ajhahn.de
← eeco
Go 42 lines
package hooks

import (
	"bytes"
	"path/filepath"
	"strings"
	"testing"
)

// TestBoundary_SessionEmitDegradesOpenOnMalformedMemory pins the background
// arm of the H1.6 degrade matrix: a session-start hook must never disrupt a
// developer's session, so when the pinned-memories store is corrupt the block
// is omitted and Emit still returns a clean partial (fail-OPEN, exit 0).
// Paired with internal/brief TestBoundary_BriefFailsClosedOnMalformedMemory,
// which pins the foreground `eeco go` fail-CLOSED posture. The asymmetry is
// intentional (Option A, H1.6) — no production change.
func TestBoundary_SessionEmitDegradesOpenOnMalformedMemory(t *testing.T) {
	cfg := newEmitCfg(t)
	// MANDATORY: the pinned-bodies swallow path is gated behind this flag.
	// Without it the block is skipped before LoadAll and the test passes
	// trivially.
	cfg.SessionStartPinnedBodies = true

	// A good pinned fact: would normally produce the pinned-memories block.
	writePinnedFact(t, cfg, "policy-x", "important", "body", true)
	// A malformed sibling: memory.LoadAll now aborts the whole load.
	writeFile(t, filepath.Join(cfg.Workspace, "memory", "broken.md"), "---\nname: broken\n")
	// A non-memory reading-routine source so Emit still has clean output.
	writeFile(t, filepath.Join(cfg.RepoRoot, "README.md"), "# Hi\n")

	var buf bytes.Buffer
	Emit(cfg, &buf) // returning at all proves no panic

	got := buf.String()
	if strings.Contains(got, "pinned memories") {
		t.Errorf("malformed store must omit the pinned-memories block (fail-open), got:\n%s", got)
	}
	if !strings.Contains(got, "README.md") {
		t.Errorf("degrade-open must still emit the clean reading-routine partial, got:\n%s", got)
	}
}