Skip to content

DataLayer create() bypasses wire→core normalisation for StorableRecord payloads #2283

Description

@sei-ahouseholder

Problem

SqliteDataLayer.create() stores a StorableRecord's data_ payload
verbatim, bypassing the wire→core normalisation that Record.from_obj /
object_to_record applies on every other write path.

vultron/adapters/driven/datalayer_sqlite/crud.py:50-53:

if isinstance(record, StorableRecord):
    rec = Record(id_=record.id_, type_=record.type_, data_=record.data_)

Record.from_obj is where _project_shadowing_wire_obj / _normalize_to_core
live (vultron/adapters/driven/db_record.py, added in #2232). Handing
crud.create a StorableRecord skips them entirely, so a wire-shaped payload
(rm_state / vfd_state flat, or camelCase keys) can be persisted under a
core type_ such as "CaseParticipant" or "VulnerabilityCase".

save() and save_many() are unaffected — both go through
object_to_record.

Why it matters

A row written this way is a shape mismatch the read path then has to repair.
That repair now exists (_from_row projects wire-spelled rows back to core via
to_core(), #2278), but it is a read-side rescue for a write-side defect: the
canonical persisted shape is only canonical on the paths that normalise
(SDO-03-002, ADR-0036, ADR-0062, DL-05-002).

Known callers of the bypass

  • vultron/core/behaviors/helpers.pyUpdateObject and CreateObject both
    build StorableRecord(data_=...) straight from blackboard dicts, so any BT
    node writing through them inherits the bypass.
  • Any direct dl.create(StorableRecord(...)) call.

Suggested direction

Route StorableRecord payloads through the same normalisation as
Record.from_obj before insert — either by calling the normaliser on data_
in crud.create, or by having StorableRecord construction go through
Record.from_obj. Needs a decision about whether normalisation should be able
to reject a write (raise) or only rewrite it, which is why this is not folded
into #2278.

Discovered by

/pr-triage on PR #2278 (finding phase8-normalize-bypassed-by-crud-write-path-0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions