KB-7D32

08 — Orphan / Phantom / Notification Contract (Branch H)

7 min read Revision 1
registries-pivotorphanphantomnotificationbranch-hlaw-definition-gapsystem-issuesevent-outboxregister-before-emit2026-05-31

title: 08 — Orphan / Phantom / Notification Contract (Branch H) date: 2026-05-31 verdict: orphan = REUSE scanners; phantom = LAW_DEFINITION_GAP AND proposed def is unreliable (model-dependent); notification = REUSE system_issues+event_outbox, register 3 new issue types + count_integrity/pin/label events mutation: none (0 issues written, 0 events emitted)

08 — Orphan / Phantom / Notification Contract (Branch H)

A. ORPHAN — REUSE existing definition + scanners

  • Def (Đ26 v3.9 / Đ19): missing birth record OR missing minimum relationship set. Live system_issues halves: thiếu_quan_hệ (606, open 0) + thiếu_mã_định_danh (9, open 0).
  • Detection (live fns): fn_birth_onboarding_full_scan(_hc) (new-object/Side-B), fn_refresh_orphan_col/_dot/_species (+trg) → meta_catalog.orphan_count. Live Σ = 161, entirely on the 3 meta rollup rows (CAT-DOT 140, CAT-COL 20, CAT-SPE 1); leaf-level orphan = 0 (doc 03).
  • Note: the orphan issues are currently closed (open=0) while orphan_count=161 persists on the rollup rows → the column is a scan snapshot, the issues are resolved; reconcile cadence is the open question, not the definition.
  • Pivot dim: by composition_level/species. PIVOT_MISSING: PIV-30x orphan-total. Severity HIGH. Cleanup: birth/registration (Side A). Notify: the two thiếu_* types.

B. PHANTOM — LAW_DEFINITION_GAP (do NOT pretend solved) + the proposed def is UNRELIABLE

  • Status: no phantom law article. De-facto signals: apr_phantom_applied (1, open 1) + the frontend-injected CAT-PHA from gap-math (an Đ28 violation, doc 09).
  • Proposed operational def (doc 06 design): phantom = counted but no backing real row → record_count − actual_count where positive.
  • NEW FINDING — this def cannot be applied uniformly: the live drift rows show the surplus direction is source_model-dependent (doc 03):
    • model-A (Directus): record_count tracks the live pivot and actual_count is the stale field → a record>actual surplus is stale-scan noise, NOT phantom (CAT-023 birth: record 980,378 = PIV-019 live; actual 943,726 stale → the 36,652 are real births, not phantoms).
    • model-B (File): record>actual can be genuine phantom (registry rows with no backing file — CAT-006: 309 rows, 163 files, 146 likely phantom ≈ CAT-DOT orphan 140).
  • Therefore the phantom operational definition must be: a counted unit whose substrate cannot be located by the source's own scanner — and it must be scoped per source_model (file-existence for model-B; live-pivot reconciliation for model-A), never a blind record−actual. Law patch required: define phantom (and its per-model detection) as a council-ratified clause; until then phantom stays LAW_DEFINITION_GAP and the surface renders phantom as PIVOT_MISSING / warning_flag=phantom(unconfirmed).
  • Cleanup: model-A → recount via refresh_meta_catalog_from_pivot; model-B → file-existence scan. Notify: propose count_integrity_phantom.

C. UNMONITORED / UNREGISTERED / GHOST / mis-stabled (REUSE / DEFER)

concept live anchor status
UNMONITORED collection_onboarding_gap (345 open) REUSE
UNREGISTERED information_schema.tables ∖ meta_catalog.source_location scan exists (Đ23 §4.2)
GHOST (cross-store) kb_pg_sync_drift (82 open) — needs Qdrant read DETECTION_DEFERRED
mis-stabled (nhầm chuồng) sai_lệch_dữ_liệu (2) LAW_DEFINITION_GAP (fold under Đ24/26/29)

D. Notification spine (live) — what to REUSE vs REGISTER

system_issues issue_type distribution (live, top): template_gap 173,378 (open all) · NULL issue_type 4,843 (the SoT itself has untyped rows — a data-quality gap) · thiếu_quan_hệ 606 · silent_fail 546 · collection_onboarding_gap 345 · dot_bug 170 · kb_pg_sync_drift 82 · hc_finding_sql 72 · hardcode_violation 10 · thiếu_mã_định_danh 9 · hc_finding_builtin 5 · sai_lệch_dữ_liệu 2 · apr_phantom_applied 1 · hc_finding_function 1 …

Reuse (no new type): thiếu_quan_hệ, thiếu_mã_định_danh, collection_onboarding_gap, sai_lệch_dữ_liệu (drift), kb_pg_sync_drift (ghost), hardcode_violation/hc_finding_* (Đ28). Propose NEW (confirmed absent): count_integrity_failed, count_integrity_phantom, label_missing.

event_type_registry (40): has issue_opened/issue_resolved/issue_archived (REUSE for the issue lifecycle), plus collection/proposal/structure/staging/governance families. Absent → must register before emit: count_integrity.*, pin.created/pin.removed, label.classify.

E. Cleanup-trigger contract (design-only; Đ45 signal-not-data, MOT-not-executor)

on detect(condition, scope):
  upsert system_issues(issue_type=<reuse|new>, severity, entity_type=scope.kind, entity_code=scope.code,
                       source='registries-pivot-count-integrity',
                       coalesce_key=condition||':'||scope.code,   -- idempotent, occurrence_count bumps
                       evidence_snapshot=json{counted,actual,orphan,phantom,gap,last_scan_date}, status='open')
  emit event_outbox(event_type=<registered>, payload=signal-ref to the issue row)   -- DESIGN
  -- governed cleanup workflow consumes, keyed by issue_type:
  --   thiếu_*                  -> birth/registration (Side A)
  --   count_integrity_*        -> refresh_meta_catalog_from_pivot + recount, then re-evaluate
  --   collection_onboarding_gap-> fn_birth_onboarding_full_scan
  --   label_missing            -> label.classify (governed, Đ24)
  --   hardcode_violation       -> developer finding (no auto-fix)

Hard rules: never hide a mismatch (visible issue + surface flag); idempotent via coalesce_key; signal-not-data; register-before-emit; the scanner never self-executes cleanup; the integrity check registers as an Đ31 self-verification contract.

F. This session

Contract documented. Zero system_issues rows written; zero events emitted; no cleanup executed. All detection in docs 03/04 was read-only / BEGIN..ROLLBACK.

Back to Knowledge Hub knowledge/dev/reports/architecture/registries-pivot-p0-p1-count-integrity-view-rehearsal-2026-05-31/08-orphan-phantom-notification-contract.md