Skip to content

fix: attribute-relations 정책이 'path node 제외'를 보증하지만 path 가 리터럴을 통과한다 #329

Description

@SeoyunL

요약

factlog init 이 사용자에게 써 주는 policy/attribute-relations.md 는 attribute 관계의 객체가
"엔티티·path node·count subject 에서 제외된다" 고 보증한다. entity 축은 약속대로 동작하지만
path 는 리터럴을 노드로 통과한다. 날짜·금액 같은 리터럴이 엔티티 그래프의 중간/종점 노드가
된다.

거짓 보증이 있는 곳이 README 가 아니라 사용자가 직접 받아 읽고 편집하는 정책 파일이고,
path 는 결정론 엔진의 산출물이라 "엔진이 검증한다" 는 계약 안에 있다.

재현 (upstream/main c6d359d, Python 3.12 로 실측)

import sys; sys.path.insert(0, '.'); sys.path.insert(0, 'tools')
from factlog.common import dependency_path, entity_set

def R(s, r, o):
    return {"subject": s, "relation": r, "object": o,
            "status": "accepted", "source": "sources/a.md"}

facts = [R("갑봇", "통합", "을서비스"), R("을서비스", "정식_운영", "2030.1")]
attrs = {"정식_운영"}          # policy/attribute-relations.md 에 선언

entity_set(facts, attrs)
# ['갑봇', '을서비스']                     <- 리터럴 2030.1 은 엔티티에서 제외 (약속대로)

dependency_path(facts, "갑봇", "2030.1")
# ['갑봇', '을서비스', '2030.1']           <- 같은 리터럴이 path 노드 (약속과 반대)

엔진 경로도 같다. 방출되는 프로그램의 edge 규칙에 attribute 필터가 없으므로
path("갑봇", "2030.1")? 는 검증된 긍정으로 답해진다.

근거

보증factlog/cli.py:428-430 이 스캐폴드하는 policy/attribute-relations.md 주석:

# Objects of these relations are kept OUT of the entity set (so they do not show
# up as entities, path nodes, or count subjects) but remain valid, verifiable
# relation-query objects.

구현factlog/common.py:1551-1556 의 엔진 프로그램:

.decl edge(start: symbol, target: symbol)
edge(S, O) :- relation(S, R, O).
path(S, O) :- edge(S, O).
path(S, O) :- edge(S, M), path(M, O).

edge 는 모든 relation/3 을 무조건 받는다. attribute 관계를 제외하는 절이 없다.
entity_set()vocab/status/entity_audit/ask_router/merge_candidates 에서만 쓰이고,
path 평가 경로는 entity_set 을 참조하지 않는다. 파이썬 렌더러 dependency_path 도 같은
필터 부재를 공유한다(위 실측).

영향

  • 심각도 중간. 크래시나 데이터 손상은 없지만, path 질의의 답이 정책 선언과 어긋난다.
  • 리터럴이 중간 노드가 되면 의미 없는 연결이 생긴다 — 같은 날짜를 가진 두 엔티티가
    그 날짜를 경유해 "연결됨" 으로 나온다. 엔티티 그래프 질의의 신뢰도가 떨어진다.
  • 정책 파일의 문구는 사용자가 attribute 선언 여부를 결정하는 근거다. 그 근거가 틀리면
    사용자는 선언으로 얻는 효과를 잘못 예측한다.

제안

택1 (구현 vs 문서 정정 — 구현 쪽이 정합):

  1. 구현을 보증에 맞춘다: edge 규칙에서 attribute 관계를 제외한다. 이미 attr_rel 계열
    선언이 프로그램에 방출되고 있으므로, edge(S, O) :- relation(S, R, O), !attr_rel(R).
    형태로 좁힐 수 있다. dependency_path 의 파이썬 렌더러에도 같은 필터를 적용해 두 경로가
    같은 답을 내게 한다. count subject 축도 함께 확인한다.
  2. 또는 정책 파일의 문구에서 "path nodes, count subjects" 를 빼고, 실제 효과(entity 목록 제외)
    만 적는다.

수용 기준

  • attribute 로 선언된 관계의 객체가 path 결과에 노드로 나타나지 않는다(엔진·파이썬 양쪽).
  • attribute 선언이 없는 KB 의 path 결과 불변(회귀 없음).
  • attribute 객체를 대상으로 한 relation 질의는 계속 정상 동작한다
    ("remain valid, verifiable relation-query objects" 보증 유지).
  • count subject 축도 보증대로인지 확인하고, 어긋나면 함께 맞춘다.
  • 정책 파일의 세 축을 각각 고정하는 테스트.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions