The SCM observer has 21 unit tests in backend/internal/observe/scm/observer_test.go and 4 store tests in backend/internal/storage/sqlite/store/store_test.go covering WriteSCMObservation, but there is no test that wires the observer to a real SQLite store and a real Lifecycle Manager and asserts the end-to-end behavior. backend/internal/integration/lifecycle_sqlite_test.go does not touch observe/scm (grep confirms zero matches). This is the largest single test gap on the SCM lane and the most likely place for a regression to land silently — the kind of regression that the messenger-and-origin wiring issue (#108) is specifically vulnerable to.
Acceptance
A new test file backend/internal/integration/scm_observer_test.go that:
PR #87 carries internal/integration/prpoller_functional_test.go with this exact shape on the older observe/prpoller design — translate the assertions onto observe/scm.Observer + ApplySCMObservation and keep the test.
Why now
This test is the regression guard for #108. Land it after #108 (or in the same PR) so the wired behavior stays wired.
Related
The SCM observer has 21 unit tests in
backend/internal/observe/scm/observer_test.goand 4 store tests inbackend/internal/storage/sqlite/store/store_test.gocoveringWriteSCMObservation, but there is no test that wires the observer to a real SQLite store and a real Lifecycle Manager and asserts the end-to-end behavior.backend/internal/integration/lifecycle_sqlite_test.godoes not touchobserve/scm(grep confirms zero matches). This is the largest single test gap on the SCM lane and the most likely place for a regression to land silently — the kind of regression that the messenger-and-origin wiring issue (#108) is specifically vulnerable to.Acceptance
A new test file
backend/internal/integration/scm_observer_test.gothat:sqlite.Storeagainst a tmpdir DB.lifecycle.Managerwith a recording in-memory messenger spy.observe/scm.Providerreturning cannedports.SCMObservationvalues keyed by PR.observe/scm.New(provider, store, lcm, Config{Tick: time.Hour})and drivesPoll(ctx)directly (do not rely on the ticker).prrow reflects the observation (provider-neutral columns, hashes set).pr_checksrows match the observation'sCI.Checks.Pollproduces zero new nudges (idempotency).Merged: trueobservation, that the session isMarkTerminated'd and no nudge is sent.PR #87 carries
internal/integration/prpoller_functional_test.gowith this exact shape on the olderobserve/prpollerdesign — translate the assertions ontoobserve/scm.Observer+ApplySCMObservationand keep the test.Why now
This test is the regression guard for #108. Land it after #108 (or in the same PR) so the wired behavior stays wired.
Related
internal/integration/prpoller_functional_test.go.