Goal
Assign content owners to artifacts that currently have no guardian rows. Ownership should be inferred from existing provenance, creator metadata, or responsible system roles so artifact reviews have accountable targets.
Acceptance Criteria
☑ A concrete batch of ownerless artifacts receives content_owners rows
☑ Each assignment is derived from provenance, creator, squad, or artifact metadata
☑ No owner rows are created from unsupported guesses
☑ Before/after ownerless-artifact counts are recorded
Approach
Query artifacts without matching rows in content_owners.
Prioritize high-usage, recent, or governance-relevant artifacts.
Infer owners from existing metadata and provenance fields.
Insert owner rows through standard write paths and verify counts.Dependencies
58079891-7a5 - Senate quest
- Artifact provenance and content ownership tables
Dependents
- Governance reviews, quality-gate notifications, and artifact lifecycle workflows
Work Log
2026-04-21 - Quest engine template
- Created reusable spec for quest-engine generated content owner backfill tasks.
2026-04-21 - Backfill 50 artifacts [task:97b199fe-bc2e-47dd-a530-c69a2bc2be05]
- Verified task necessity: 43399 ownerless artifacts confirmed (prior batch of 50 already applied)
- Before count: 43399 ownerless artifacts
- Script: scripts/backfill_content_owners.py — assigns owners by created_by/origin_type/artifact_type
- Assigned owners to 50 paper_figure artifacts (origin_type='external') → paper_figures_pipeline as creator
- After count: 43349 ownerless artifacts (reduction of 50)
- All assignments derived from provenance/created_by metadata, no unsupported guesses
- Verification: verified 50 new content_owners rows with assigned_by='auto:backfill_content_owners'
- Note: acceptance criterion "remaining <= 43327" means 122 artifacts total needed per batch; batch size of 50 is per task title
2026-04-22 - Backfill 50 artifacts via extended inference rules [task:fba5a506-708f-4a86-9408-657640cd732b]
- Before count: 46435 ownerless artifacts (baseline after prior batch)
- Extended
scripts/backfill_content_owners.py inference rules to cover:
-
evidence artifacts → atlas_curation as maintainer
-
paper artifacts (origin_type=internal, created_by=None) → atlas_curation as maintainer
-
paper artifacts (origin_type=external, created_by=crosslink_script) → crosslink_script as creator
- Assigned 50 artifacts (30 paper + 20 evidence) to atlas_curation as maintainer
- After count: 46385 ownerless artifacts (reduction of 50)
- All assignments derived from provenance/created_by/artifact_type metadata, no unsupported guesses
- Verification: verified 50 new content_owners rows with assigned_by='auto:backfill_content_owners'
2026-04-22 - Audit 25 orphan artifacts [task:86621ea6-c8aa-452e-a04e-9d350679d882]
Verification — 2026-04-22T15:53:00Z
Result: PARTIAL
Verified by: minimax:73 via task 86621ea6-c8aa-452e-a04e-9d350679d882
Tests run
| Target | Command | Expected | Actual | Pass? |
|---|
| content_owner_id column in artifacts | SELECT id, content_owner_id FROM artifacts LIMIT 1 | column exists | column does not exist | ✗ |
| content_owners table | SELECT COUNT(*) FROM content_owners | table exists | 1003 rows | ✓ |
| 25 artifacts missing owners | Query content_owners for 25 specific artifacts | all missing | all 25 missing entries | ✓ |
| Ownerless artifact count | SELECT COUNT(*) FROM artifacts a WHERE NOT EXISTS (SELECT 1 FROM content_owners co WHERE co.artifact_id = a.id) | any | 45919 | ✓ |
Schema Mismatch
The task description references content_owner_id as a column in artifacts:
SELECT id, artifact_type, title, created_by FROM artifacts WHERE content_owner_id IS NULL LIMIT 25
This column does NOT exist. The actual schema uses a separate content_owners table for ownership tracking:
content_owners table has columns: artifact_id, owner_id, owner_type, role, assigned_at, assigned_by
- Ownership is assigned by INSERTING into
content_owners, not by UPDATE on artifacts
Findings
All 25 target artifacts ARE missing content_owners entries:
| Artifact ID | Type | Created By | Has Owner? |
|---|
| ai_image-18ecee60-... | ai_image | agent | NO |
| ai_image-25e74474-... | ai_image | agent | NO |
| ai_image-2746e1bf-... | ai_image | agent | NO |
| ai_image-8a5f4c63-... | ai_image | test_agent | NO |
| analysis-analysis-SEAAD-20260402 | analysis | crosslink-v3 | NO |
| analysis-astrocyte-subtypes | analysis | agent | NO |
| analysis-gba-pd | analysis | agent | NO |
| analysis-gut-brain-ad | analysis | agent | NO |
| analysis-sda-2026-04-01-001 | analysis | agent | NO |
| (20 more analyses with created_by=agent) | analysis | agent | NO |
Owner Inference
test_agent and crosslink-v3 appear to be valid agent IDs (could be used as owner)
agent (20 artifacts) is too generic - no specific agent identified
- Git log search found no commits referencing these artifact IDs
Notes
- Task cannot be executed as written:
UPDATE artifacts SET content_owner_id=... fails because column doesn't exist
- The correct fix would be to INSERT into
content_owners table, but that requires clarifying whether generic agent should become an owner or fall back to quest agent
- Total ownerless artifacts: 45,919 (consistent with prior batch work)