Tests the mandatory SGM Core capabilities: Store, Retrieve, Read, Identity, Scope, Discovery. Every conforming implementation MUST pass all of these.
Each test is Given/When/Then over public operations only.
Given: a valid memory record with id="c1" in scope {project: "conf"}
When: the implementation stores it, then retrieves with {ids:["c1"], scope}
Then: the record is returned with identical content, type, and id.
Given: a record id="c2" stored once
When: the same id is stored again with the same content
Then: retrieval returns exactly one record for id="c2" (no duplicate).
Given: a stored record with a complete provenance object
When: the record is read
Then: every provenance field (agent, created_at, origin, scope) is
returned unmodified.
Given: a record with type="future-type" (not in the enum) and custom
metadata
When: stored then retrieved
Then: the record returns with type="future-type" and metadata intact —
not rejected, not coerced.
Given: a record in scope {project: "alpha"}
When: retrieval runs in scope {project: "beta"}
Then: the alpha record is NOT returned.
Given: a record in scope {project: "alpha", session: "s1"}
When: retrieval runs in scope {project: "alpha"} without cross-scope request
Then: the narrower-scoped record is not assumed accessible by default per the
implementation’s declared behavior; if returned, it MUST carry its own scope.
Given: any stored record
When: it is retrieved
Then: provenance.agent and provenance.created_at are present and
non-empty.
Given: a fresh implementation
When: capability discovery is invoked
Then: the response contains protocol_version, implementation, and a
capabilities array that includes "core".
Given: a fresh implementation
When: capability discovery is invoked
Then: protocol_version is a valid version string the consumer can parse.
Given: a query that matches nothing
When: retrieval runs
Then: the result is an empty records array with total: 0 — NOT an error
object.
Given: a record carrying a reference object
When: stored then retrieved
Then: the reference object is returned intact (even if the implementation
cannot resolve its content).
Given: a record missing a required field (e.g. no scope)
When: the implementation attempts to store it
Then: it returns invalid_record with a message, and does not store it.