Skip to content

Unify the durable-meta IRI term classifier across ingest (durable-integrity) and responder read (graph-plan) #1940

Description

@Jurij89

Context

#1921 (PR #1936) makes the "durable _meta subject must be an IRI" invariant span both the ingest and read paths, but the string-prefix term classifier is currently implemented in two private helpers:

  • isIriMetaSubject in packages/agent/src/sync/durable-integrity.ts (ingest admission)
  • isIriTerm in packages/agent/src/sync/responder/graph-plan.ts (responder read/paging)

They share the core contract (reject terms starting with _: or "), coupled today by a comment rather than by code.

Deliberate current difference (not a bug)

isIriMetaSubject('') returns false (fail-closed hardening: an empty/malformed _meta subject is dropped at admission), whereas the responder's isIriTerm('') returns true. This divergence is intentional and safe: the responder read path never sees an empty term post-ingest. It is called out here so unification is a conscious decision, not a silent behavior change.

Proposed follow-up

Extract a single canonical term-classifier in the layer that owns the string-encoded Quad contract (e.g. a shared sync/storage util) and import it from both durable-integrity and graph-plan. Decide explicitly how the shared helper treats the empty-string case (unifying to fail-closed would change the responder read path and needs its own review/tests). Cover the shared helper with IRI / blank-node / literal / empty-string cases.

Why deferred from #1921

#1921's scope is the ingest guard + its checkpoint-advance correctness. Unifying the classifier would reach into the responder read path (graph-plan.ts) and alter its empty-string handling — a separate, independently-reviewable change. Tracked here to keep #1921 focused.

Related: #1921, PR #1936. Raised by otReviewAgent on PR #1936 (durable-integrity.ts ~:1454 thread).

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