@@ -297,6 +297,7 @@ func (s *SQLiteStore) migrate() error {
297297 created_at TEXT NOT NULL DEFAULT (datetime('now')),
298298 updated_at TEXT NOT NULL DEFAULT (datetime('now')),
299299 deleted_at TEXT,
300+ created_by TEXT,
300301 FOREIGN KEY (session_id) REFERENCES sessions(id)
301302 );
302303
@@ -386,6 +387,7 @@ func (s *SQLiteStore) migrate() error {
386387 {name : "last_seen_at" , definition : "TEXT" },
387388 {name : "updated_at" , definition : "TEXT NOT NULL DEFAULT ''" },
388389 {name : "deleted_at" , definition : "TEXT" },
390+ {name : "created_by" , definition : "TEXT" },
389391 }
390392 for _ , c := range observationColumns {
391393 if err := s .addColumnIfNotExists ("observations" , c .name , c .definition ); err != nil {
@@ -3078,6 +3080,11 @@ func (s *SQLiteStore) migrateLegacyObservationsTable() error {
30783080 return nil
30793081 }
30803082
3083+ // Legacy tables predate created_by; ensure it exists before the copy below reads it.
3084+ if err := s .addColumnIfNotExists ("observations" , "created_by" , "TEXT" ); err != nil {
3085+ return err
3086+ }
3087+
30813088 tx , err := s .beginTxHook ()
30823089 if err != nil {
30833090 return fmt .Errorf ("migrate legacy observations: begin tx: %w" , err )
@@ -3103,6 +3110,7 @@ func (s *SQLiteStore) migrateLegacyObservationsTable() error {
31033110 created_at TEXT NOT NULL DEFAULT (datetime('now')),
31043111 updated_at TEXT NOT NULL DEFAULT (datetime('now')),
31053112 deleted_at TEXT,
3113+ created_by TEXT,
31063114 FOREIGN KEY (session_id) REFERENCES sessions(id)
31073115 );
31083116 ` ); err != nil {
@@ -3113,7 +3121,7 @@ func (s *SQLiteStore) migrateLegacyObservationsTable() error {
31133121 INSERT INTO observations_migrated (
31143122 id, sync_id, session_id, type, title, content, tool_name, project,
31153123 scope, topic_key, normalized_hash, revision_count, duplicate_count,
3116- last_seen_at, created_at, updated_at, deleted_at
3124+ last_seen_at, created_at, updated_at, deleted_at, created_by
31173125 )
31183126 SELECT
31193127 CASE
@@ -3136,7 +3144,8 @@ func (s *SQLiteStore) migrateLegacyObservationsTable() error {
31363144 last_seen_at,
31373145 COALESCE(NULLIF(created_at, ''), datetime('now')),
31383146 COALESCE(NULLIF(updated_at, ''), NULLIF(created_at, ''), datetime('now')),
3139- deleted_at
3147+ deleted_at,
3148+ created_by
31403149 FROM observations
31413150 ORDER BY rowid;
31423151 ` ); err != nil {
@@ -3401,7 +3410,8 @@ func (s *SQLiteStore) PromoteObservation(id int64, identity string) error {
34013410}
34023411
34033412// ListContributors returns contributor activity stats from observations and prompts.
3404- // SQLite stub — does not have per-row created_by in all builds, returns empty.
3413+ // SQLite — created_by is only populated on rows synced from a multi-user backend;
3414+ // local-only writes leave it NULL, so this typically returns empty.
34053415func (s * SQLiteStore ) ListContributors (project string ) ([]ContributorStats , error ) {
34063416 obsQuery := `
34073417 SELECT COALESCE(created_by, '') as identity,
0 commit comments