pub fn reflect(
conn: &Connection,
input: &ReflectInput,
) -> Result<ReflectOutcome, ReflectError>Expand description
v0.7.0 recursive-learning Task 4/8 (issue #655) — substrate-native reflection primitive.
Steps (matches the MCP tool contract):
- Validate inputs (
title,content, namespace, tags, priority, confidence, agent_id, source_ids). - Load each source memory; bail with
ReflectError::SourceNotFoundon any missing id (no partial write). - Compute
new_depth = max(source.reflection_depth) + 1. - Resolve the effective namespace cap via
resolve_governance_policy(walks the ancestor chain leaf- first), fall back toGovernancePolicy::defaultwhen the chain has no policy at any level, then callGovernancePolicy::effective_max_reflection_depthon the resolved policy. - Refuse with
ReflectError::DepthExceededwhennew_depth > max_dep. - Insert the new reflection memory and write a
reflects_onlink from the new memory to each source — all inside a singleBEGIN IMMEDIATE…COMMITblock. Any insert / link failure rolls back the entire write so a half-written reflection cannot survive.
The new memory’s metadata is the caller-supplied object with a
system-generated reflection_metadata key spliced in (recording
the source-id list, the resolved depth, and the RFC3339 creation
timestamp). Caller-supplied keys win on collision — if the
caller already supplied reflection_metadata we honor their value
and skip the system splice. This is the documented additive contract.
The agent_id field on the input bundle is stamped into
metadata.agent_id before insert; the caller is responsible for
resolving it via crate::identity::resolve_agent_id.
§Errors
Returns one of the four ReflectError variants. The DB-error
variant is the only one with no structured payload — every other
variant carries enough information for the caller to render a clean
operator-readable message and (for DepthExceeded) for Task 5/8 to
emit a structured audit row.