KG modification audit log

← All Specs

Goal

The kg_modifications table already exists in the schema but has no code that writes to it. This task implements the write path so every KG edge creation, update, and deletion is recorded with before/after state, contradictions found, and approval status — enabling rollback and audit.

Acceptance Criteria

_record_kg_modification() helper function written in scidex/core/db_writes.py
insert_knowledge_edge() logs a 'create' entry to kg_modifications
update_knowledge_edge() logs an 'update' entry with before/after state
delete_knowledge_edge() logs a 'delete' entry with before state
/api/rollback/{edit_id} logs a 'rollback' entry to kg_modifications
☑ All entries include actor_id, reason, source, and timestamps
☑ Contradictions field is available for future use

Approach

  • Add _record_kg_modification() helper in scidex/core/db_writes.py
  • Call it from insert_knowledge_edge(), update_knowledge_edge(), and delete_knowledge_edge()
  • Add kg_modifications logging to the /api/rollback/{edit_id} handler for knowledge_edge content_type
  • Test by verifying syntax and import checks pass
  • Work Log

    2026-04-17 10:25 PT — Slot minimax:64

    • Task is a reopen after prior attempt could not verify work landed on main
    • Confirmed: table exists (kg_modifications), index exists (idx_kg_mods_created)
    • Confirmed: table is EMPTY (0 rows) — no code writes to it
    • Confirmed: insert_knowledge_edge, update_knowledge_edge, delete_knowledge_edge in db_writes.py do NOT log to kg_modifications
    • Confirmed: rollback handler does NOT log to kg_modifications
    • Added _record_kg_modification() helper to scidex/core/db_writes.py
    • Updated insert_knowledge_edge() to call helper on create
    • Updated update_knowledge_edge() to call helper on update with before/after state
    • Updated delete_knowledge_edge() to call helper on delete with before state
    • Updated /api/rollback/{edit_id} to log rollback entries
    • Syntax checks pass for both modified files
    • Code compiles and imports correctly against live DB
    • Rebased onto latest origin/main (5 new commits applied cleanly)

    Verification — 2026-04-19 11:30:00Z

    Result: PASS Verified by: minimax:63 via task t-kg-modification-log

    Tests run

    TargetCommandExpectedActualPass?
    _record_kg_modification function exists in db_writes.pygrep '_record_kg_modification' origin/main:scidex/core/db_writes.pypresentpresent
    insert_knowledge_edge calls helpergrep -n '_record_kg_modification' origin/main:scidex/core/db_writes.py3 calls at lines 473,505,5353 calls
    update_knowledge_edge calls helpergrep -n '_record_kg_modification' origin/main:scidex/core/db_writes.pycall at 505call at 505
    delete_knowledge_edge calls helpergrep -n '_record_kg_modification' origin/main:scidex/core/db_writes.pycall at 535call at 535
    rollback handler in api.pygrep 'INSERT INTO kg_modifications' origin/main:api.pypresent at 15736present at 15736
    Python syntax checkpython3 -m py_compile scidex/core/db_writes.py api.pyno errorsno errors
    Function importsfrom scidex.core.db_writes import _record_kg_modification, insert_knowledge_edge...OKOK

    Attribution

    The current passing state is produced by:

    • 30fdef44a — Add kg_modifications audit log to KG edge operations [task:t-kg-modification-log] (verified on origin/main)

    Notes

    • Work from commit 30fdef44a is present on origin/main (verified via git show origin/main:...)
    • Table schema (kg_modifications) was created in a prior migration (api.py lines 1678-1693)
    • Rollback handler uses inline SQL (not _record_kg_modification helper) due to API context; this is acceptable
    • _record_kg_modification uses ctx.agent_id from journal context as fallback for actor_id
    • Task is a reopen from 2026-04-17; code landed on main on that date

    File: t-kg-modification-log.md
    Modified: 2026-04-25 17:55
    Size: 4.1 KB