Skip to content

[schemas] enhanced-thoughts: sync RPCs with current ExoCortex behavior#37

Open
alanshurafa wants to merge 1 commit into
mainfrom
contrib/alanshurafa/enhanced-thoughts-rpc-sync
Open

[schemas] enhanced-thoughts: sync RPCs with current ExoCortex behavior#37
alanshurafa wants to merge 1 commit into
mainfrom
contrib/alanshurafa/enhanced-thoughts-rpc-sync

Conversation

@alanshurafa

Copy link
Copy Markdown
Owner

What this does

The enhanced-thoughts schema shipped an older generation of the upsert_thought and search_thoughts_text RPCs than the reference brain has been running. This PR closes that gap. Everything is additive and idempotent — re-running schema.sql on a v1 install is a no-op, and the v1 return contract ({id, fingerprint}) plus the status / status_updated_at handling that workflow-status depends on are left exactly as they were.

Changes

  • search_thoughts_text learns date and tier filters. p_filter now reads three reserved control keys — start_date, end_date (ISO 8601), and exclude_restricted (boolean) — and applies them at the data layer. They are peeled off before the metadata @> filter containment check, so any other key keeps its old behavior.

  • upsert_thought gets two dedup/merge guards.

    • Original-fingerprint fallback. When a thought's content is corrected its fingerprint changes; a later reimport of the original text used to insert a stale sibling that outvoted the correction. If the pre-edit fingerprint lives in an append-only metadata.original_fingerprints[] array, the reimport now lands on the corrected row instead.
    • User-edit guard. Keys listed in metadata.user_edits are treated as human-owned and stripped from an incoming automated patch, so a reimport can't clobber a human correction. Guards metadata keys only.
    • To make the fallback possible the function does an explicit lookup and branches INSERT vs UPDATE instead of ON CONFLICT. The unique-index race that ON CONFLICT handled for free is caught explicitly and folded back into the merge path.
  • New opt-in match_thoughts_superseded_aware. Same shape as the core match_thoughts plus a superseded_by column. Thoughts that have been replaced (the target of a supersedes edge in thought_edges) take a 0.8x ranking penalty so fresh thoughts surface above their stale predecessors, without ever being excluded. The core match_thoughts is untouched; callers opt in by name, matching the recency-boosted-match-thoughts pattern. Installed only when schemas/typed-reasoning-edges/ is present; otherwise it's skipped with a NOTICE and the rest of the migration still applies.

ID contract

All ported references use UUID against public.thoughts(id). The superseded-aware RPC returns superseded_by UUID and reads thought_edges where from_thought_id is the newer replacement and to_thought_id is the stale thought — the directional semantics OB1's typed-reasoning-edges already documents.

Importance scale

ExoCortex widened its own importance to 0-6. Open Brain's upsert already accepts a wider 0-100 range, so it never clipped 0-6 values — switching to 0-6 here would retroactively rescale every existing row, which is a breaking data change, not an additive one. The 0-100 clamp stays; the README documents 0-6 as a subset for cross-system parity.

Testing

Applied against a throwaway PostgreSQL instance with stub thoughts + thought_edges tables:

  • Insert returns {id, fingerprint}; re-insert dedupes to the same row.
  • Original-fingerprint reimport lands on the corrected row (no stale sibling; content preserved).
  • User-edit guard keeps a human title against a robot overwrite.
  • start_date and exclude_restricted filters return the expected subset.
  • match_thoughts_superseded_aware returns the stale row at 0.8x with superseded_by set, fresh row at full similarity.
  • Re-running schema.sql is clean; dropping thought_edges triggers the documented skip-with-NOTICE.

Compatibility

Preserves the workflow-status dependency documented in NateBJones-Projects#328upsert_thought still writes status / status_updated_at, and the README's Prerequisites now call out workflow-status explicitly.

Existing installs ran older upsert/search RPCs than the reference brain.
This brings them current without breaking the v1 contracts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e2b89072c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +478 to +479
WHERE jsonb_typeof(t.metadata->'original_fingerprints') = 'array'
AND t.metadata->'original_fingerprints' ? v_fingerprint

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not let stale imports overwrite corrected embeddings

When this fallback matches, v_id belongs to the corrected row even though p_content is the old text. The existing capture flow I checked in integrations/open-brain-rest/index.ts:409-439 uses the returned id to write a newly computed embedding and metadata for p_content; reimporting an original fingerprint therefore overwrites the corrected row's embedding/metadata with stale data instead of leaving the correction untouched. This only occurs for rows with metadata.original_fingerprints, but it breaks the main dedup-correction scenario this path is adding.

Useful? React with 👍 / 👎.

Comment on lines +103 to +104
AND (NOT v_exclude_restricted
OR coalesce(t.sensitivity_tier, 'standard') <> 'restricted')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor metadata sensitivity when excluding restricted rows

When callers pass exclude_restricted=true, this condition only checks the promoted sensitivity_tier column. Rows captured before this schema, or by stock/canonical flows that store the tier in metadata (for example schemas/provenance-chains/schema.sql reads metadata->>'sensitivity_tier' for that reason), get the column default standard and are not backfilled here, so restricted metadata rows still come back from the new filtered search. Use the metadata tier as a fallback or backfill it before relying on this filter for lower-trust surfaces.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant