Skip to content

[schemas] thought_audit table for multi-participant attribution#230

Open
txcfi-scott wants to merge 1 commit intoNateBJones-Projects:mainfrom
txcfi-scott:contrib/txcfi-scott/thought-audit
Open

[schemas] thought_audit table for multi-participant attribution#230
txcfi-scott wants to merge 1 commit intoNateBJones-Projects:mainfrom
txcfi-scott:contrib/txcfi-scott/thought-audit

Conversation

@txcfi-scott
Copy link
Copy Markdown

What it does

Adds a thought_audit table plus an author_session_id convention, so who changed what, when becomes answerable once more than one participant writes to the same Open Brain.

The problem. Once you have Claude Desktop, Codex, a ChatGPT API worker, and a nightly importer all writing to the same thoughts table, updates and deletes are effectively anonymous — nothing records which session or which agent did what. For a personal brain that is fine. For a shared brain, or for debugging "why did this thought disappear?", it is painful.

The solution. An append-only audit table that records every mutation, plus a small convention (metadata.author_session_id) that lets you cluster all writes from a single agent session.

How it stays safe

  • Additive only. No existing thoughts columns are altered or dropped. No existing functions are replaced. Fully idempotent — safe to re-run.
  • No foreign key. thought_audit.thought_id deliberately has no FK to thoughts(id) so audit rows survive deletion of their subject (the most important audit event to preserve).
  • INSERT-only grants. service_role gets SELECT, INSERT on the audit table — never UPDATE or DELETE. Nothing downstream can rewrite history without an explicit, reviewed migration that temporarily grants DELETE.
  • Best-effort writes. The README documents the audit-insert pattern as fire-and-forget: a failure to record an audit row must never block the main capture / update / delete.

Example audit trail

t=10:00  capture  source=claude-desktop     session=sess-AAA  thought-123
t=10:05  update   source=claude-desktop     session=sess-AAA  thought-123 (metadata patch)
t=11:30  update   source=chatgpt-api        session=sess-BBB  thought-123 (content rewrite)
t=15:00  delete   source=codex-cli          session=sess-CCC  thought-123 (previous_content preserved)

One SELECT * FROM thought_audit WHERE thought_id = '...' ORDER BY created_at returns the full provenance.

What it requires

  • Working Open Brain setup (just the thoughts table).

No additional services. No LLM calls.

Companion integrations

This schema is storage-only — the actual audit writes live in the mutation tools. Two companion integrations in separate PRs wire them up:

If those PRs are still open when this one is reviewed, the README examples here are the authoritative reference. The schema itself has zero runtime dependency on the integrations — you can install it and write audit rows from your own mutation code if you prefer.

Tested

  • Ran schema.sql and author-session-id.sql twice against a fresh and a populated Supabase Open Brain. Both runs complete idempotently with no errors.
  • Attempted UPDATE thought_audit ... and DELETE FROM thought_audit WHERE ... as service_role; both correctly reject with "permission denied for table thought_audit" — confirming the append-only grant works.
  • Wrote three audit rows (capture / update / delete) and queried by thought_id, author_session_id, and created_at; all three indexes get used.
  • Dropped a thought, confirmed the delete audit row remains with diff.previous_content preserved.

Files touched

Only schemas/thought-audit/ — stays within the contribution scope check.

Adds thought_audit: an append-only log of every capture/update/delete
on the thoughts table, with source + author_session_id for attribution
across Claude Desktop / Codex / ChatGPT / importer writes.

Strictly additive — no existing thoughts columns altered, no existing
functions replaced. Grants are INSERT-only, so nothing downstream can
rewrite history without an explicit migration.

An optional second SQL file adds a thought_provenance view and a
thoughts_by_session() RPC for querying by session id.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the schema Contribution: database extension label Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

schema Contribution: database extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant