Quickstart
reconcile
Check saved SQL against warehouse actual_sample or a HubSpot CRM contract against row-free crm_evidence; mismatches become caveats.
reconcile checks a saved definition against source evidence collected by your agent. It is the step that distinguishes a context layer from a notes file: when declared context and observed evidence disagree, the entry becomes a caveat; otherwise it remains asserted.
In the personal MCP reconciliation path, ClariLayer never receives your warehouse or CRM credentials, runs your SQL, or calls a CRM provider. The agent uses its own authorized connection and sends one of the two supported evidence shapes in capability v43: warehouse actual_sample or bounded, row-free HubSpot crm_evidence. HubSpot reconciliation is generally available to authenticated organizations behind the mandatory server-side global emergency switch. Salesforce remains store/recall-only.
The two evidence paths
The stored definition selects exactly one path:
- Warehouse/SQL definition: the agent runs stored SQL and passes
actual_samplewith result columns, an optional bounded row preview, and an optional row count. - CRM definition: the agent passes mutually exclusive
crm_evidencecontaining only declared property metadata and value distributions. HubSpot is the only reconcilable CRM provider in the current v43 contract. Salesforce contracts can be remembered and recalled, but after CRM access passes reconcile returnscrm_provider_not_enabled.
For both paths, a successful check replaces the entry's current evidence detail and updates last_checked. It does not append another live evidence blob. Public reconcile output does not include verified_at and no verified status/result ships.
Store a CRM definition
Use remember with type: "definition" and a strict crm contract. CRM contracts cannot be combined with metric or sql. This minimal HubSpot example declares one internal property value:
{
"type": "definition",
"name": "Lifecycle stage contract",
"content": "The lifecycle value used by this workflow.",
"crm": {
"schema_version": 1,
"provider": "hubspot",
"object_api_name": "contacts",
"properties": [
{
"name": "lifecyclestage",
"expected_values": [{ "value": "customer" }]
}
]
}
}
expected_values and canonical_value.value are positive record-usage assertions: the declared internal value is expected to occur in the property's record distribution. A normalized internal identifier may appear in exactly one of expected_values, canonical_value.value, or canonical_value.deprecated_aliases; in particular, do not repeat the canonical value in expected_values. Deprecated aliases are conflict candidates, not values expected to remain in use. The canonical presence assertion is independent and requires positive canonical record usage. Positive deprecated-alias usage is a conflict signal; for a complete distribution, the alias-conflict check is inconsistent when the canonical value and an alias both have positive counts. expected_label is a separate option-metadata assertion and does not establish record usage. Use provider internal object/property/value identifiers, not display labels, as filter operands.
Configured-but-unused is intentionally different from configured-but-present. An option can exist in HubSpot metadata while having zero record usage. For an expected or canonical value, absence or an exact zero count in a complete record distribution is inconsistent with reason absent_from_complete_distribution; that means absent from populated records in the complete distribution, not missing from HubSpot configuration. Missing or truncated distributions remain asserted-only, as does a zero lower_bound count. Every emitted crm_enum_value_present detail therefore carries evidence_basis: "record_distribution". Reconcile does not issue a separate provider-configuration check.
Complete HubSpot agent recipe
Do not hard-code connector tool names. Provider connectors change their surface; capability-probe the connected provider and choose a bounded read path it actually advertises.
- Recall the relevant context. When a result says
has_crm_contract: true, callget_context_entryand use the complete storedbody.crmcontract. Do not reconstruct the contract from a truncated recall summary. - Inspect the connected provider's capabilities. Request metadata for only the contract's declared
object_api_nameand declared property names. Report a property asunavailableor omit it when the connector cannot inspect it; never turn a failed read intoabsent. - Prefer a bounded aggregation/count capability for each required property distribution. Collect only internal values, optional labels, counts, precision, completeness, and the cap when applicable.
- If no aggregation capability exists, use the provider's official search/list API through the connected provider, page it, and aggregate locally. Set an explicit record/page cap before starting. Do not persist the executable request or connector-specific tool name into ClariLayer.
- Mark a distribution or option list
completeonly after every page is exhausted. If a provider, connector, pagination, or local safety cap stops collection, mark ittruncatedand include the actual positivecap. A value missing from truncated evidence is inconclusive, never evidence of absence. - Use
status: "unavailable"(or omit the observation) for a failed or inaccessible property lookup. Usestatus: "absent"only when authoritative metadata positively reports the declared property absent. - Normalize the envelope before calling
reconcile: include only the declared provider, object, property metadata, and distributions. Never send CRM records/rows,sample_rows, credentials/tokens, undeclared properties, executable provider queries, connector names as persisted dependencies, or raw provider payloads. The recursive row ban rejectssample_rowsanywhere, including under unexpected nesting. - Set count precision honestly.
exactmeans the count is complete for that value under the collection method.lower_boundmeans at least that many were observed, but more may exist. A positive lower bound proves presence; a zero lower bound never proves absence.
A complete row-free evidence envelope for the example above is:
{
"entry_id": "<saved-entry-id>",
"crm_evidence": {
"schema_version": 1,
"provider": "hubspot",
"object_api_name": "contacts",
"properties": [
{ "name": "lifecyclestage", "status": "present" }
],
"distributions": [
{
"property": "lifecyclestage",
"completeness": "complete",
"values": [
{
"value": "customer",
"count": { "value": 7, "precision": "exact" }
}
]
}
]
}
}
Only send evidence after the full contract is fetched and the provider read is complete enough to label honestly. Normalized CRM evidence is capped at 128 KiB; the final stored verification detail is capped at 1 MiB.
CRM availability and failure boundaries
HubSpot reconcile is generally available for authenticated organizations. A mandatory server-side global emergency switch remains authoritative and fail-closed; when it is off, CRM reconcile returns crm_reconcile_disabled. The production operation and rollback procedure belongs in the repository runbook, not in the agent's evidence payload.
After CRM access passes, a Salesforce definition returns crm_provider_not_enabled, because Salesforce contracts are store/recall-only. A HubSpot definition without an evidence envelope returns crm_evidence_required. Strictly malformed or row-bearing crm_evidence is rejected at the MCP schema boundary as JSON-RPC -32602 InvalidParams. Schema-accepted evidence that is semantically mismatched or exceeds the byte bounds returns crm_evidence_mismatch. None of these errors downgrades the definition or manufactures a successful check.
Warehouse workflow
For a stored SQL definition, the agent runs the SQL using its own warehouse access and calls reconcile with actual_sample. ClariLayer extracts declared signals from the stored SQL and compares them with the supplied result shape. Optional preview rows may contain sensitive values and are persisted with the warehouse verdict evidence, so omit or redact them when columns and row count are sufficient.
A natural prompt is:
Reconcile our Active Customer definition: fetch its complete stored context, run its SQL with my warehouse connection, and compare the result shape in ClariLayer.
The warehouse path remains distinct from CRM: never send actual_sample for a CRM definition, and never send crm_evidence for a warehouse definition.
Honest outcomes
reconcile has two trust outcomes:
caveat— at least one applicable declared check conflicts with the supplied evidence.asserted— no applicable check conflicted. This may include checks that were inconclusive because evidence was missing, unavailable, or truncated.
A clean run does not create a stronger status. Inconclusive evidence stays asserted-only at the check level, and a missing value becomes inconsistent only when a complete distribution establishes that absence. Read Verified vs Asserted for the trust model.
After a relevant successful reconcile, the managed completion loop calls context_checkpoint with the active entry as evidence. The durable, idempotent receipt persists the agent's context_updated declaration and validates ownership and eligibility of the referenced ClariLayer object. It does not independently prove that the entry changed, that the warehouse query or CRM source is semantically correct, or that any external code deployed.
When to reconcile
- When two reports or workflows use different internal values.
- After a warehouse schema or CRM property/options change.
- Before relying on a definition for a consequential analysis or automation.
- When a deprecated CRM alias may still be active beside its canonical value.
See also
- remember — capture the definition that reconcile checks.
- recall — recalled entries carry
assertedorcaveat. - AI Agent Context Guide — use reconcile inside the recall-first loop.
- Verified vs Asserted — the trust-status model.