What's on your mind?
Summary
There appears to be schema drift around how OB1 represents the source of a thought.
Observed patterns include:
- Stock/core write paths and source filtering guidance use
thoughts.metadata.source, queried in SQL as thoughts.metadata->>'source'.
- Newer dashboard, schema, integration, and stats contributions read or write a dedicated
thoughts.source_type column.
- Some current contributions write both fields, or perform a follow-up update to set
source_type after calling stock upsert_thought, because stock upsert_thought only persists p_payload->'metadata'.
- At least one prior recipe discussion exposed confusion around whether
source belongs as a top-level thoughts column versus inside thoughts.metadata.
This makes it unclear which representation new recipes, dashboards, migrations, and user-contributed integrations should target.
(This issue was AI-generated with OpenAI Codex)
Why This Matters
If one component writes only thoughts.metadata.source while another reads only thoughts.source_type, source filtering, dashboard grouping, statistics, and backfill workflows can silently miss records.
If thoughts.source_type is intended to be an enhanced-schema projection or denormalized index-friendly representation of thoughts.metadata.source, that should be documented explicitly. If it is intended to replace thoughts.metadata.source, then recipes and existing source-filtering guidance likely need migration guidance.
This is especially important because the current stock setup guide's upsert_thought(p_content, p_payload) stores only p_payload->'metadata'. A caller that sends sibling top-level keys such as source_type can succeed while silently leaving enhanced columns unset unless it performs a second update or mirrors the value into metadata.
Current Observed Patterns
Related but Not Duplicate
Questions for Maintainers
- What is the canonical source attribution field for OB1 going forward:
thoughts.metadata.source, thoughts.source_type, or both?
- If both are supported, is
thoughts.source_type intended to be a denormalized/generated/indexed projection of thoughts.metadata.source, or an independent field?
- Should stock
upsert_thought populate source_type from p_payload->>'source_type', from p_payload->'metadata'->>'source', or leave enhanced columns to follow-up updates?
- Should dashboards and source filters query a compatibility expression such as
coalesce(thoughts.source_type, thoughts.metadata->>'source')?
- Should recipes write only the canonical representation, or should they write both fields for compatibility?
- Would maintainers accept pull requests that document the canonical model, normalize recipes to that model, update dashboard queries, add a compatibility view/RPC/helper, and provide migration/backfill guidance?
Possible Contribution Path
- Document the canonical source attribution model.
- Clarify whether
upsert_thought should populate enhanced columns from payload keys or metadata.
- Add a read-side compatibility helper such as
effective_source.
- Update dashboard queries to use
effective_source or an equivalent coalesce(...) expression.
- Update recipes to write the canonical field consistently.
- Add migration/backfill guidance for installations that already have only one representation.
Reference Links
Repository References
Discord Discussion References
What's on your mind?
Summary
There appears to be schema drift around how OB1 represents the source of a thought.
Observed patterns include:
thoughts.metadata.source, queried in SQL asthoughts.metadata->>'source'.thoughts.source_typecolumn.source_typeafter calling stockupsert_thought, because stockupsert_thoughtonly persistsp_payload->'metadata'.sourcebelongs as a top-levelthoughtscolumn versus insidethoughts.metadata.This makes it unclear which representation new recipes, dashboards, migrations, and user-contributed integrations should target.
(This issue was AI-generated with OpenAI Codex)
Why This Matters
If one component writes only
thoughts.metadata.sourcewhile another reads onlythoughts.source_type, source filtering, dashboard grouping, statistics, and backfill workflows can silently miss records.If
thoughts.source_typeis intended to be an enhanced-schema projection or denormalized index-friendly representation ofthoughts.metadata.source, that should be documented explicitly. If it is intended to replacethoughts.metadata.source, then recipes and existing source-filtering guidance likely need migration guidance.This is especially important because the current stock setup guide's
upsert_thought(p_content, p_payload)stores onlyp_payload->'metadata'. A caller that sends sibling top-level keys such assource_typecan succeed while silently leaving enhanced columns unset unless it performs a second update or mirrors the value into metadata.Current Observed Patterns
Source filtering work documents a
sourceparameter forsearch_thoughts,list_thoughts, andthought_stats:[recipes] Source filtering for Open Brain thoughts #30
Slack deduplication recipe discussion uses
thoughts.metadatafor source-specific event identity, and also surfaced confusion about top-levelsourcecolumns versus JSONB metadata:[recipes] Slack message deduplication pattern for thought ingestion #89
The dashboard contribution was merged under
dashboards/open-brain-dashboard-next/, and appears relevant to source/type filtering behavior:[dashboards] Full-featured web dashboard for thought management #111
Enhanced schema work adds
thoughts.source_typeas an idempotent structured column onthoughts:[schemas] Enhanced thoughts columns and utility RPCs #191
Brain health monitoring views read
source_typefor source volume and enrichment gap monitoring:[recipes] Brain health monitoring views #194
Consolidation worker work treats
source_typeas part of prepared payloads and notes that stockupsert_thoughtcan drop sibling top-level fields liketype,importance, andsource_typeon first-run inserts:[integrations] Consolidation workers (bio + metadata) #200
Synthesis capture work mirrors provenance into metadata because stock
upsert_thoughtdrops top-level payload keys; its anti-loop checks read top-levelsource_typewhen available:[recipes] Synthesis capture — Query-as-Ingest pattern #212
Brain stats daily and heatmap work depends on
source_typefrom the enhanced-thoughts schema:[schemas] Brain stats daily + heatmap filter #221
Wiki pipeline work includes a fallback from
source_typeto metadata-derived source fields when the column is not present:[recipes] Wiki pipeline: OpenRouter + thought_edges + prompt safety #234
Readwise capture/import work writes both
source_type = 'readwise'andmetadata.source = 'readwise', and documents that some RPCs filter onsource_type:[integrations] Add Readwise highlight capture (backfill + webhook + schema) #237
The open-brain-rest gateway writes through stock
upsert_thoughtwithmetadata.source, then separately updates top-levelsource_typefor dashboard reads:[integrations] open-brain-rest — Cloudflare Worker REST gateway for the Next.js dashboard #239
Related but Not Duplicate
Standardizing ingestion patterns is already tracked separately:
[architecture] Standardize thought ingestion patterns across recipes and integrations #61
That issue is broader. This issue is specifically about canonical source attribution and read/write compatibility between
metadata.sourceandsource_type.A prior closed issue reported similar drift for
type: a migration assumed a top-levelthoughts.typecolumn on a stock schema where type lived inmetadata->>'type':[schemas] workflow-status migration fails: type column does not exist on thoughts table #182
The fix changed the workflow-status backfill to read
metadata->>'type'instead:[repo] Sweep fix-now backlog issues #185
That prior fix does not resolve source attribution, but it shows the same class of confusion around stock metadata fields versus enhanced top-level columns.
Questions for Maintainers
thoughts.metadata.source,thoughts.source_type, or both?thoughts.source_typeintended to be a denormalized/generated/indexed projection ofthoughts.metadata.source, or an independent field?upsert_thoughtpopulatesource_typefromp_payload->>'source_type', fromp_payload->'metadata'->>'source', or leave enhanced columns to follow-up updates?coalesce(thoughts.source_type, thoughts.metadata->>'source')?Possible Contribution Path
upsert_thoughtshould populate enhanced columns from payload keys or metadata.effective_source.effective_sourceor an equivalentcoalesce(...)expression.Reference Links
Repository References
Source filtering recipe:
[recipes] Source filtering for Open Brain thoughts #30
Slack message deduplication recipe:
[recipes] Slack message deduplication pattern for thought ingestion #89
Dashboard contribution merged as
dashboards/open-brain-dashboard-next/:[dashboards] Full-featured web dashboard for thought management #111
Enhanced thoughts columns adding
thoughts.source_type:[schemas] Enhanced thoughts columns and utility RPCs #191
Brain health monitoring views:
[recipes] Brain health monitoring views #194
Consolidation workers:
[integrations] Consolidation workers (bio + metadata) #200
Synthesis capture:
[recipes] Synthesis capture — Query-as-Ingest pattern #212
Brain stats daily and heatmap filter:
[schemas] Brain stats daily + heatmap filter #221
Wiki pipeline source fallback:
[recipes] Wiki pipeline: OpenRouter + thought_edges + prompt safety #234
Readwise capture/import:
[integrations] Add Readwise highlight capture (backfill + webhook + schema) #237
open-brain-rest gateway:
[integrations] open-brain-rest — Cloudflare Worker REST gateway for the Next.js dashboard #239
Standardize thought ingestion patterns:
[architecture] Standardize thought ingestion patterns across recipes and integrations #61
Prior
typedrift report and fix:[schemas] workflow-status migration fails: type column does not exist on thoughts table #182
[repo] Sweep fix-now backlog issues #185
Discord Discussion References
Discussion of controlled vocabulary inside
thoughts.metadata:https://discord.com/channels/1481783256641699840/1481789897470906429/1482622942121689169
Discussion of migrating/custom schema overlap involving
source_typeand JSONB metadata:https://discord.com/channels/1481783256641699840/1481790073392599041/1482874122747777095
Discord notification/discussion for the Slack deduplication metadata recipe:
https://discord.com/channels/1481783256641699840/1481790377534034101/1484302480127950879