KB-6A3D

S175 Closure Verify Report

9 min read Revision 1
reports175closureverify

S175 Closure Verify Report

Date: 2026-04-09 Mode: READ-ONLY Agent: Claude Code Goal: Verify S175 fix is permanent and complete

Result: PARTIAL PASS

4 of 5 verify points fully PASS. C3 found 1 BYPASS path (reconcile-knowledge.py) — risk MEDIUM, no immediate impact since not on automated trigger.


C1 — Code fix in runtime image: PASS

Evidence

Container vs source file checksum match:

docker exec incomex-agent-data md5sum /app/agent_data/directus_sync.py
→ f6eb710a67e2f9eb393886a1db30a9a6  /app/agent_data/directus_sync.py

md5sum /opt/incomex/docker/agent-data-repo/agent_data/directus_sync.py
→ f6eb710a67e2f9eb393886a1db30a9a6  /opt/incomex/docker/.../directus_sync.py

_db_conn() in runtime container has commit:

@contextmanager
def _db_conn():
    conn = psycopg2.connect(_db_dsn())
    conn.autocommit = False
    try:
        yield conn
        conn.commit()         # ← S175 P3 fix present
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()

Image ID matches build:

docker inspect incomex-agent-data --format '{{.Image}}'
→ sha256:bfe092449032e23ee9ad091f5a327e11b29f4b5d9757aa9c40cace5a588dd5b7

docker images agent-data-local:latest --format '{{.ID}}'
→ bfe092449032

Runtime image = built image. Code change deployed correctly.


C2 — Schema constraint complete: PASS

Index definition

SELECT indexdef FROM pg_indexes WHERE indexname = 'idx_kd_current_source_id_unique';
CREATE UNIQUE INDEX idx_kd_current_source_id_unique
ON public.knowledge_documents USING btree (source_id)
WHERE ((is_current_version = true) AND (source_id IS NOT NULL))

Predicate exactly: is_current_version=true AND source_id IS NOT NULL

Reject test (in transaction, rolled back)

BEGIN;
INSERT INTO knowledge_documents (..., source_id) VALUES (...,
  'agentdata:knowledge/current-state/reports/agent-data-connectivity-check-gpt-2026-03-31.md');
ROLLBACK;

Output:

BEGIN
ROLLBACK
ERROR: duplicate key value violates unique constraint "idx_kd_current_source_id_unique"
DETAIL: Key (source_id)=(agentdata:...) already exists.

PG correctly rejects. Constraint working.


C3 — Bypass writer paths: PARTIAL — 1 BYPASS FOUND

grep -rn 'INSERT INTO knowledge_documents\|UPDATE knowledge_documents' /opt/incomex/docker/agent-data-repo/
→ (no direct SQL writes outside _sync_document_atomic)

grep -rn 'items/knowledge_documents' /opt/incomex/docker/agent-data-repo/
→ /scripts/reconcile-knowledge.py:71  GET (read only — OK)
   /scripts/reconcile-knowledge.py:149 POST (CREATE — bypass)
   /scripts/reconcile-knowledge.py:171 PATCH (UPDATE — bypass)
   /scripts/test-agent-connections.sh:142 POST (test — low risk)
   /webhook_config.json:23 (webhook config — read only)

BYPASS #1: reconcile-knowledge.py

File: /opt/incomex/docker/agent-data-repo/scripts/reconcile-knowledge.py Lines 149 (POST), 171 (PATCH): Direct REST API writes to Directus, bypassing the atomic writer.

Code path:

def create_directus_doc(token, doc_id, content, metadata):
    payload = {
        "title": title, "slug": slug, "file_path": doc_id,
        "source_id": f"agentdata:{doc_id}", ...
        "version_group_id": str(uuid.uuid4()),
    }
    api("POST", f"{DIRECTUS}/items/knowledge_documents", payload, ...)

Risk: This script does its own slug/version_group_id generation and POST to Directus REST API. It does NOT:

  • Lock by source_id (no pg_advisory_xact_lock)
  • Run in a single PG transaction
  • Mark old current rows as is_current_version=false before inserting new

However, the partial UNIQUE constraint idx_kd_current_source_id_unique (S175 P2) WILL reject any attempt to create a duplicate current row. So the schema serves as last-line defense.

Impact assessment:

  • Not on cron/automated trigger (manual run only)
  • Schema constraint prevents data corruption
  • Could fail with cryptic error if run today (would hit UNIQUE violation on existing rows)
  • Risk: MEDIUM — flag for cleanup but no immediate corruption

BYPASS #2: test-agent-connections.sh line 142

curl -X POST "$OPS_URL/items/knowledge_documents" -d '{"test":1}'

This is a test/probe script. Risk LOW (one-off, not in production cron).

Webhook config

webhook_config.json line 23 is config-only, declaring a webhook target. Not a write path.


C4 — 2-worker listener registration: PASS (with metric caveat)

Container exec

docker inspect incomex-agent-data --format '{{.Path}} {{join .Args " "}}'
→ bash -lc uvicorn agent_data.server:app --host 0.0.0.0 --port ${PORT:-8080} --workers 2

2 workers confirmed.

EventBus singleton pattern (per process)

File event_system.py:

# Line 424
_event_bus: EventBus | None = None

# Line 427-432
def get_event_bus() -> EventBus:
    global _event_bus
    if _event_bus is None:
        _event_bus = _build_event_bus()
    return _event_bus

# Line 466-468
from agent_data.directus_sync import directus_sync_listener
bus.add_listener(directus_sync_listener)

Each uvicorn worker = separate Python process = separate _event_bus singleton. Both workers register directus_sync_listener independently.

events_logged sampling (5x)

events: 3 listeners: 1
events: 3 listeners: 1
events: 3 listeners: 1
events: 1 listeners: 1   ← worker B
events: 3 listeners: 1

Interpretation: events_logged is per-worker counter. Most /health calls hit worker A (count=3), one hit worker B (count=1). This is a metric inconsistency, NOT a functional bug.

Functional impact: NONE. Each request is handled end-to-end by 1 worker:

  1. PUT /documents → routed to worker (e.g., A)
  2. Worker A's listener fires → calls atomic writer → writes Directus PG
  3. Worker B doesn't need to know — DB is the SSOT

Caveat for operators: events_logged from /health is misleading; should be aggregated across workers for accurate metric. Out of S175 scope.


C5 — Backfill & smoke test integrity: PASS

NULL source_id count

SELECT COUNT(*), array_agg(id) FROM knowledge_documents
WHERE is_current_version=true AND source_id IS NULL;
→ count=3, ids={298,299,301}

3 NULLs remaining = exactly the 3 README dup NULLs deferred to followup. ✓

Spot check 3 backfilled rows (random)

 id  |                          file_path                           |                               source_id                                | pattern_ok
-----+--------------------------------------------------------------+------------------------------------------------------------------------+------------
 302 | knowledge/current-tasks/task-list.md                         | agentdata:knowledge/current-tasks/task-list.md                         | t
 980 | knowledge/current-state/reports/s155-p1c-close-loop-report   | agentdata:knowledge/current-state/reports/s155-p1c-close-loop-report   | t
 983 | knowledge/current-state/reports/s150-p0-investigation-report | agentdata:knowledge/current-state/reports/s150-p0-investigation-report | t

All 3 follow exact pattern agentdata:<file_path>. ✓

Smoke test doc 964 still consistent

id=964 | version_number=3 | date_updated=2026-04-09 09:28:14.72428
length(content)=1356 | is_current_version=t

Matches end state from VIỆC 4 (version=3 after restore, original content). ✓


Overall Verdict: PARTIAL PASS — 4/5 fully clean, 1 bypass flagged

Check Status Notes
C1 Code fix in runtime PASS md5 match, image ID match
C2 Schema constraint PASS Index correct, INSERT rejected
C3 No bypass PARTIAL reconcile-knowledge.py is BYPASS (MEDIUM risk)
C4 Worker listeners PASS Both register, metric caveat
C5 Backfill integrity PASS 3 NULLs as planned, spot check OK

Risks Still Open

  1. reconcile-knowledge.py bypass — Script can be invoked manually, would create duplicates if not for the partial UNIQUE constraint catching it. Recommended: refactor to call atomic writer or document as deprecated.

  2. 3 README NULL rows — Already in followup s175-readme-duplicates-followup.md.

  3. Move endpoint deprecated (S170) — Cross-path renames are 2-step (upload + delete), no atomicity. Out of S175 scope.

  4. Worker metric inconsistencyevents_logged per-worker. Cosmetic. Out of S175 scope.

Unknowns / Need clarification

None. All 5 checks have evidence.