Skip to main content

ABOX - Data Access API User Guide

UserAPIVersion 0.8.1

Purpose

api.m manages the ABox, data-level transaction records describing entity instances (their attribute values, relationships, and history). It mirrors the structure of sapi.m (which manages TBox schema metadata) but stages into %ABR instead of %TBR, and commits via the same StageTransact pattern.

Where sapi.m defines what attributes exist and how they behave, api.m records what entities exist and what their current and historical attribute values are. Every write is immutable, retractions and revisions preserve full datom history in ^EATV, making the entire transaction log auditable at any point in time.

ABox Region

The ABox (Assertion Box) is stored in a dedicated YottaDB database region (abox.dat) with journal file (abox.mjl).
The ABox contains the assertions and retractions on “the actual data. It describes specific individuals (instances) and how they relate to the concepts defined in the TBox (Terminological Box). Think of it as the populated database.

  • Focus: Individuals (Instances).
  • Example: “Socrates is a Man” or “This specific blue Ford has 4 Wheels”
  • RDF Context: This corresponds to the actual triples that describe your resources
GlobalDescription
^ABEABox entity index — registers every entity ever asserted. ^ABE(eid,1)="" marks the entity as live. Root node holds total entity count.
^EATVPrimary datom store — ^EATV(eid,aid,tx,valkey)=op. The authoritative record of every assertion and retraction. Subscript order supports efficient entity-centric queries.
^AVETSecondary index — ^AVET(aid,valkey,eid,tx)=op. Supports lookup of entities by attribute value e.g. find entity with imdbid="tt0109830".
^AEVTColumn index — ^AEVT(aid,eid,valkey,tx)=op. Supports retrieval of all values for a given attribute across all entities, comparable to the traditional column access style.
^VAETReverse-reference index — ^VAET(valkey,aid,eid,tx)=op. Written only for reference-typed attributes. Supports reverse traversal from a referenced entity to all entities that reference it.

In all five datom indexes node values store op=1 as an assertion and op=0 as a retraction. ^EATV, ^AVET, ^AEVT, and ^TXE are written for every datom. ^VAET is written only for reference-typed attributes, where reverse relationship traversal is required. All index updates occur atomically within the same transaction.

EATV Global

In YottaDB, each datom is physically represented as a node within the EATV (Entity-Attribute-Transaction-Value) index. The EATV global provides the primary storage layout for entity reconstruction and current-state resolution.

The logical datom represents the relationship: (eid, aid, tx, val, op) and is mapped to the YottaDB node structure

^EATV(eid, aid, tx, val) = op

The EATV global stores datoms about an entity ordered by:

  • eid — Entity identifier. The unique identifier of the entity to which the fact applies.
  • aid — Attribute identifier. The attribute whose value is being asserted or retracted.
  • tx — Transaction identifier. A monotonically increasing transaction order representing when the fact change was recorded by the system.
  • val — Attribute value (valkey). Attribute value. The value associated with the attribute.
  • op — Operation type indicating the truth state transition: either an assertion or retraction
  • The node value represents the truth state of the fact at the given transaction point::
    • T = denotes an assertion indicating that the triplet (eid, aid, val) is TRUE at transaction tx.
    • F = denotes a retraction indicating that the triplet (eid, aid, val)is FALSE at transaction tx.

Datom Definition

A datom is the fundamental unit of fact storage in a temporal fact-based system. It represents a single assertion or retraction of an attribute value for an entity at a specific transaction point in time.

A datom is immutable once recorded. State changes are represented by adding new datoms rather than modifying or deleting existing ones. A datom is not a mutable attribute value. It is an immutable historical statement about the truth state of a fact at a specific transaction point. The complete history of an entity is the set of all datoms associated with that entity. The current state is derived by evaluating the latest datoms for each (eid, aid) pair.

In this example:

eidaidtxvalop
Alicesalary7418$1200T
Alicesalary7420$1200F
Alicesalary7420$1800T
Bobsalary7401$1000T
Bobsalary7410$1000F
Bobsalary7410$1200T
Bobsalary7420$1200F
Bobsalary7420$1500T
Fredsalary7420$2200T
Johnsalary7406$1400T
Johnsalary7420$1400F
  • alice sorts before bob,
  • bob before fred,
  • fred before john,
  • and within each entity the tx values increase monotonically.

In YottaDB, global subscripts are automatically ordered in collation order. Consequently, the EATV index can be traversed naturally in eid → aid → tx → val order without requiring a separate sorting mechanism. The EATV index ordering allows efficient traversal from an entity and attribute directly to its transaction history, making it optimized for entity reconstruction and current-state reads.

Primitive Operations

There are two primitive operations implemented in a fact-based temporal oriented system

  • Assert
    Meaning: assert operation records and affirms the fact that an entity attribute has this specific value at a point in time.
    Establish a fact as TRUE at T
    Example: It is TRUE that Bob’s salary is $1500 at 7420.
  • Retract
    Meaning: retract operation records and states that a previously asserted fact is no longer true (i.e. FALSE)
    Establish that a previously asserted fact is FALSE at T
    Example: At 7420 Bob’s salary IS NOT $1400 (FALSE)

A Compound Derived Operation

  • Revise
    Meaning: changes the value of an entity attribute by retracting the currently asserted value at time (t1) and asserting the new value at time (t2). The truth status of one fact at t1 has changed, and a new fact now holds at t2.
  • Example:
    At 7420, Bob’s salary is revised from $1400 to $1500. This is established from the composite fact that
    At 7420 Bob’s salary IS NOT $1400. At 7420 Bob's salary IS $1500.
Revise(E, A, V_old, V_new, T) ≡ Retract(E, A, V_old, T) + Assert(E, A, V_new, T)

Current State Definition

The current value of (eid,aid) is determined by:

  1. Locate the highest transaction, max(tx), for the given (eid,aid)
  2. Examine the datom(s) at that transaction
  • Current value is TRUE
    The latest transaction of (eid,aid) contains a single assertion
    Example: At tx=7420 Fred’s salary is $2200
Fredsalary7420$2200T
  • Current revision of the value
    The latest transaction of (eid,aid)is a revision. there is a retraction and an assertion of a datom at tx
    Example: At tx=7420 Bob’s salary have been revised from $1200 to $1500
Bobsalary7420$1200F
Bobsalary7420$1500T
  • Current value is FALSE
    The latest transaction of (eid,aid) contains a single retraction
    Example: At tx=7420 John’s salary IS NOT $1400
Johnsalary7406$1400T
Johnsalary7420$1400F

The number of val entries at that transaction is bounded:

  • Assert — one val
  • Retract — one val
  • Update — two vals (one retract, one assert)

Current-state lookup therefore does not depend on historical depth. It always inspects at most two entries, regardless of how many transactions preceded it. The ^EATV global is optimized for entity reconstruction and current-state reads, because transaction order is directly accessible after (eid,aid). The most recent transaction for any entity-attribute pair can be located in a single step, with no dependency on the depth of that attribute’s history.

Stage and Transact Phases

The system separates a request to store facts in the database into two distinct phases: Stage and Transact. Thus, Stage determines and prepares which facts will be stored, while Transact atomically records those facts in the temporal fact store using YottaDB storage engine.

Initialization

Before the user submits any database request, a user session must be initialized:

INIT
	DO Setup^logger("DEBUG",1,0)
	DO INIT^sapi
	DO INIT^api
	DO Load^keywords
	QUIT

Staging Phase

The Stage phase interprets and prepares the requested changes without modifying the persistent ABox data. It resolves entity identities and attribute identities, resolves record values into their corresponding value keys, validates the input records, and converts the requested changes into primitive Assert and Retract operations. These operations are accumulated in the %ABR staging buffer, which represents the complete set of fact changes to be applied by the transaction.

Staging Phase Forms

Form 1 — Stage Record(s)
One or more entities, each with multiple attributes, expressed as a local array and staged via Stage. Supports both assertions and retractions in the same record.

	; Form 1 Example - Stage Record	
	; Set a local array that represents entity record(s)
	K M
	S M(1,"movie.title")="Seven"
	S M(1,"movie.genre")="thriller|mystery"
	S M(1,"movie.releaseYear")=1995
	S M(1,"movie.imdbid")="tt0114369"
	
	; Process local array input and stage record into %ABR buffer
	D Stage^api(.M,"sandbox")
	
	; Commit everything staged by Form 1 calls above
	D Transact^api("Root")

Form 2 — Assert / Retract Datom
An assertion or retraction of an attribute value on a single entity, staged via AD/AssertDatom or RD/RetractDatom.

Both forms write into the same %ABR buffer. Transact is always called explicitly by the caller after all staging is complete. It commits everything accumulated in %ABR as a single atomic transaction regardless of which forms were used or how many calls were made.

	; Form 2 Example — stage additional single datoms on any entity
	D AD^api(TomHanks,"obj.wiki","https://en.wikipedia.org/wiki/Tom_Hanks")
	D RD^api(TomHanks,"obj.alias","TomHanks")
	
	; Commit everything staged by Form 2 calls above
	D Transact^api("Root")

Transact

The Transact phase consumes the staged %ABR operations and performs the actual persistent update. It allocates and stamps the transaction, writes the corresponding datoms and ABox indexes, records the transaction metadata, and executes the complete operation within a YottaDB transaction (TSTART/TCOMMIT). If any failure occurs during this phase, TROLLBACK atomically discards all persistent changes.

Transaction Data Model

TaxisDB represents transaction data with YottaDB local sparse multi-dimensional sorted associative arrays, also known as globals:

  • Local — process-private and non-persistent.
  • Sparse — only assigned nodes consume memory.
  • Multi-dimensional — any number of subscripts.
  • Sorted — subscripts are maintained in collation order.
  • Associative — subscripts are keys (strings or numbers).

Transaction data is semantically an unordered set of datoms, all of which are added to the database at an atomic moment in time. TaxisDB provides two input forms for staging datoms, which can be freely combined before a single Transact commits them all atomically.

Transactions Region

The transactions region is stored in a dedicated YottaDB database region (transactions.dat). It is shared by both api.m and sapi.m. All transaction stamps, entity-transaction indexes, and log entries from both modules are written here.

GlobalDescription
^TXTransaction registry — ^TX(tx,"dt")=epoch and ^TX(tx,"user")=user. Every committed transaction is stamped with a Unix epoch timestamp and the initiating user. Root node ^TX holds the last allocated transaction ID (counter starts at 7399). Shared by both api.m and sapi.m — TBox and ABox transactions share the same sequence.
^TXEReverse transaction index — ^TXE(tx,eid)="". Maps each transaction to every entity it touched, enabling efficient lookup of all entities affected by a given transaction. Root node ^TXE holds the total count of indexed transactions. Entity IDs are numeric for TBox entities (e.g. ^TXE(7400,10)="") and 20-char KSUIDs for ABox entities (e.g. ^TXE(7403,"65592747b661d01oqks9")="").
^TXLOGProcess-level log store — ^TXLOG($JOB,session,seq)=formatted. Persists log entries for the current process, keyed by YottaDB job ID ($JOB), a per-process session number, and a sequence number that keeps increasing across sessions. Each entry is a formatted string: timestamp | name | level | message; optional $STACK trace frames are stored under ^TXLOG($JOB,session,seq,i) when tracing is on. A new session is opened by every Setup^logger/INIT^logger call — explicit ("STARTED at" / "RESTARTED at") or guard-triggered ("AUTO-STARTED at") — rather than overwriting a shared config, giving a full history of each (re)configuration. Per-session config lives under ^TXLOG($JOB,session,"CFG",*): LEVEL, OUTPUT, TRACE, SEQ, and the start-marker timestamp. Root metadata per process: ^TXLOG($JOB,"SESSIONS") holds the count of sessions opened, and ^TXLOG($JOB,"CURRENT") holds the session number LOG^logger is currently writing into.

Reverse transaction index

Reading ^TXE reveals what each transaction touched, for example:

txentities toucheddescription
7400TBox eids (100..999)Bootstrap — full schema load
	;; Entities with integer IDs are metadata entities in TBox (types, attributes, etc...)
	^TXE(7401,"6582b863e6e91xe42dms")=""  ; ABox entity
	^TXE(7401,"6582b863e703efee63un")=""  ; ABox entity
	^TXE(7402,1000)=""
	^TXE(7402,1001)=""
	^TXE(7402,1002)=""
	^TXE(7402,1003)=""
	^TXE(7403,"6582b863ed35908lsqvq")=""  ; ABox entity
	^TXE(7404,1004)=""
	^TXE(7404,1005)=""
	^TXE(7404,1006)=""
	^TXE(7404,1007)=""
	^TXE(7404,1008)=""
	^TXE(7405,"6582b863f49c5wrkzfhp")=""  ; ABox entity
	^TXE(7406,1009)=""
	^TXE(7406,1010)=""
	^TXE(7406,1011)=""
	^TXE(7406,1012)=""
	^TXE(7407,"6582b863fb545wuoird4")=""  ; ABox entity
	^TXE(7408,1013)=""
	^TXE(7409,0)=""  ; no-op 0 means there were no datoms asserted, no entity touched

Transaction index

Transactions are similar to entities, but they are recorded in a separate global in a dedicated region. They can be described with user-defined attributes, all transactions by default are time-stamped and are attributed to a specific user that is registered in the database. The default user is Root

YDB>zwr ^TX

	^TX=7409
	^TX(7400,"dt")="6582b863e6513"
	^TX(7400,"user")="Root"
	^TX(7401,"dt")="6582b863e7167"
	^TX(7401,"user")="Root"
	^TX(7402,"dt")="6582b863ebca4"
	^TX(7402,"user")="Root"
	^TX(7403,"dt")="6582b863ed3f4"
	^TX(7403,"user")="Root"
	^TX(7404,"dt")="6582b863f2835"
	^TX(7404,"user")="Root"
	^TX(7405,"dt")="6582b863f4c06"
	^TX(7405,"user")="Root"
	^TX(7406,"dt")="6582b863f985a"
	^TX(7406,"user")="Root"
	^TX(7407,"dt")="6582b863fb60e"
	^TX(7407,"user")="Root"
	^TX(7408,"dt")="6582b86941ca1"
	^TX(7408,"user")="Root"
	^TX(7409,"dt")="6582b86943b55"
	^TX(7409,"user")="Root"

Staging API

Form 1 — Stage Record(s)

Use when asserting or retracting multiple attribute values on one or more entities. Multiple records (Obj(1,...), Obj(2,...) …) are supported in one Stage call. Assertions and retractions can be mixed within the same record. Transact must be called explicitly to commit.

Existing Entity

The record must contain either sys.attr.id or sys.attr.key to identify the target entity. Resolution failure in any case is a hard error, no new entity is created and the record is aborted.

	; sys.attr.id — raw EID
	S Obj(1,id)="65569b4e16e8firp6wbf" 
	S Obj(1,"person.name")="tommy" 
	
	; sys.attr.id — compound attrkey|value lookup
	; second entity in same transaction
	S Obj(2,id)=dlcid_"|042"
	S Obj(2,"dlc.checkup")="ok"
	
	; sys.attr.key — registered entity key
	; third entity in same transaction
	S Obj(3,key)=TomHanks
	S Obj(3,"person.name")="tommy"
	S Obj(3,"person.label","-")="" ; retract from single-value attribute
	S Obj(3,alias,"-")="TomHanks"  ; retract from multi-value attribute
	
	D Stage^api(.Obj,"sandbox") 	
	D Transact^api("Root")

New Entity

No sys.attr.id is present. A new permanent eid is generated.

Case A — sys.attr.key

The key is supplied but not yet registered. sys.attr.key value becomes the permanent natural key of the new entity, making it resolvable via sys.attr.key or sys.attr.id compound format on all future transactions.

	S Obj(1,key)="obj.athan" ; not yet registered → GENID 
	S Obj(1,"person.name")="athan" 
	S Obj(1,"person.age")=56
	D Stage^api(.Obj,"sandbox")
Case B — No resolution directive

Neither sys.attr.id nor sys.attr.key is present. A new entity is created uncoditionally

    S M(17,"movie.title")="Seven"
    S M(17,"movie.genre")="thriller|mystery"
    S M(17,"movie.releaseYear")=1995
    S M(17,"movie.imdbid")="tt0114369"
    D Stage^api(.M,"sandbox") 	

	S Item(51,"dlc.id")="042"    
    S Item(51,"dlc.checkup")="Dilithium Crystals on 1st January 2013 @en"
    S Item(51,"dlc.count")=100
    S Item(51,"dlc.txdate")="2013-01-01"
    D Stage^api(.Item,"sandbox") 	

Form 2 - Assert/Retract Datom

Use when asserting or retracting a single attribute on an entity. Each call stages into %ABRTransact must be called explicitly to commit.

Entity Resolution

The first argument ekv identifies the target entity. Resolution behavior depends on the format and whether the entity exists:

FormatExampleExistsNot found
A — raw EID“654f2564f8165hevmhe6”resolved via ^EATVhard error
B — compound“sandbox.dlc.id|042”resolved via unique indexhard error
C — bare key“obj.tom_hanks”resolved via sys.attr.keyGENID → new entity

For Format C, when the key is not found a new permanent eid is generated and the ekv value becomes the sys.attr.key of the newly created entity.

AssertDatom \ AD

Existing entity
	; Format A — raw EID
	D AD^api("654f2564f8165hevmhe6","movie.title","The Reader")

	; Format B — compound attrkey|value lookup
	D AD^api("sandbox.dlc.id|042","dlc.checkup","ok")

	; Format C — bare key, entity found
	D AD^api(TomHanks,"obj.name","tommy")

	; Multi-value — "|"-delimited, expanded internally by DatomAssert
	D AD^api(TomHanks,"obj.wiki","https://en.wikipedia.org/wiki/Tom_Hanks|https://fr.wikipedia.org/wiki/Tom_Hanks")
New entity (Format C only)

When the bare key is not registered, a new entity is created.

	; "obj.athan" not found → GENID → new entity with sys.attr.key="obj.athan"
	D AD^api("obj.athan",name,"athan")

	; "sys.attr.id" not found → GENID → new entity anchored to dlcid="042"
	; sys.attr.key is never set to "sys.attr.id"
	D AD^api(id,dlcid,"042")	
  • Empty ekv, akey, or val is a hard error
  • Format A and Format B always target existing entities — resolution failure aborts

RetractDatom \ RD

Use when retracting a single attribute on an existing entity. Each call stages into %ABR
Transact must be called explicitly to commit.

Retractions always target existing entities. Format C performs a pre-validation. If the bare key is not found the call is aborted with an error before any staging occurs. Use Format A or Format B when the entity key is uncertain.

Cardinality-one

Omit val active value is resolved automatically

	; Format A — raw EID 
	D RD^api("654f2564f8165hevmhe6","person.name") 
	
	; Format B — compound attrkey|value lookup 
	D RD^api("sandbox.dlc.id|042","dlc.checkup") 
	
	; Format C — bare key, entity must exist 
	D RD^api(TomHanks,"person.name")
Cardinality-many

val is required to identify which value to retract

	; Format A — raw EID 
	D RD^api("654f2564f8165hevmhe6","obj.alias","TomHanks") 
	
	; Format B — compound attrkey|value lookup 
	D RD^api("sandbox.dlc.id|042","obj.wiki","https://en.wikipedia.org/wiki/Tom_Hanks") 
	
	; Format C — bare key, entity must exist 
	D RD^api(TomHanks,"obj.alias","TomHanks")

Test Error Cases:

	D RD^api(TomHanks,"person.name","tommy")    ; ERROR — val must be omitted for cardinality-one
	D RD^api(TomHanks,"obj.alias")              ; ERROR — val required for cardinality-many
	D RD^api("obj.unknown","person.name")       ; ERROR — Format C entity not found
	D RD^api(TomHanks,"obj.alias","Batman")     ; ERROR - value never asserted

No-op cases — not errors, logged as DEBUG:

	D RD^api(TomHanks,"person.name")            ; no active datom
	D RD^api(TomHanks,"obj.alias","TomHanks")   ; already retracted	

Validation Errors

All validation failures abort before AssertRecord opens a transaction, the record is skipped and nothing is staged for it in %ABR. If every record in the batch fails validation, Transact logs %ABR is empty — nothing to commit.

  • Unknown attribute key
  • Failed validation predicate - Each attribute’s range type enforces a predicate — e.g. STRING fields are checked for alphanumeric content, INT fields must be whole numbers.
  • Missing required attribute
  • Unique-insert violation (sys.enum.unique.insert)
  • Unique-upsert performs identity resolution (sys.enum.unique.upsert) rather than reporting an error

All five error categories share the same outcome: the offending record is rolled back or skipped, every other record in the same Stage call is validated and staged independently, and Transact commits whatever remains in %ABR.

Inspection & Reporting

These routines read ABox data for inspection. They do not stage or commit any datoms. ABox entities are data-level instances, movies, persons, inventory items, and any other domain objects managed via Stage/Transact in api.m. They are identified by 20-char KSUID eids generated via GENID, distinct from TBox numeric eids in sapi.m.

PrintEntity \ PE

Resolves an ABox entity and prints all currently active attribute values in tabular format. Only live datoms (latest tx with OP=1) are displayed — retractions and historical values are suppressed.

Entity resolution accepts three forms for val:

FormExampleDescription
raw EID"65562451b4868yhv9dwg"direct eid lookup
sys.attr.key"obj.tom_hanks"resolved via ^AVET
unique attribute value"tt0109830"requires attr to identify which attribute

attr is optional — required only for unique attribute value lookup.
Accepts either a numeric aid or a sys.attr.key string:

	; By raw EID
	DO PE^api("6557d0527ad9ef2tzszl")
	
	; By sys.attr.key
	DO PE^api("obj.tom_hanks")
	DO PE^api(TomHanks)  ; using keyword variable
	
	; By value of a unique attribute — attr required
	DO PE^api("https://en.wikipedia.org/wiki/Tom_Hanks","sys.attr.wikipage")
	DO PE^api("https://en.wikipedia.org/wiki/Tom_Hanks",wiki)   ; using keyword variable
	DO PE^api("https://en.wikipedia.org/wiki/Tom_Hanks",267)    ; using numeric aid directly
  • Cardinality-one attributes show only the most recent active value
  • Cardinality-many attributes show all active values
  • Retracted datoms and unresolved values are suppressed
YDB>D PE^api(TomHanks)

2026-06-30T20:32:05.409845 | API | DEBUG | GetEID: resolved via sys.attr.key: obj.tom_hanks

======
obj.tom_hanks
======
  6557d0527ad9ef2tzszl  sys.attr.key             obj.tom_hanks
  6557d0527ad9ef2tzszl  sys.attr.description     American actor and filmmaker (born 1956) @en
  6557d0527ad9ef2tzszl  sys.attr.alias           TomHanks
  6557d0527ad9ef2tzszl  sys.attr.alias           %TomHanks
  6557d0527ad9ef2tzszl  sys.attr.label           Tom Hanks @en
  6557d0527ad9ef2tzszl  sys.attr.name            tom_hanks
  6557d0527ad9ef2tzszl  sys.attr.wikipage        https://en.wikipedia.org/wiki/Tom_Hanks
  6557d0527ad9ef2tzszl  sys.attr.wikipage        https://fr.wikipedia.org/wiki/Tom_Hanks
  6557d0527ad9ef2tzszl  sys.attr.wikipage        https://el.wikipedia.org/wiki/Τομ_Χανκς
  6557d0527ad9ef2tzszl  sys.attr.isa             sys.type.obj

PrintHistory \ PH

Prints the complete raw ^EATV content for a resolved entity, i.e. the full datom history including retractions. Accepts the same val/attr forms as PrintEntity.

	DO PrintHistory^api("6557d1f58f6f65apmlu8")
	DO PrintHistory^api("042",dlcid)
	DO PrintHistory^api("042","sandbox.dlc.id")
	DO PrintHistory^api("042",1005)

Output — one row per (eid, aid, tx, valkey, op) tuple, all transactions:

Reading the history

This entity (dlcid="042") was first created at tx=7407 with four attributes asserted: dlcid, dlc.checkup, dlc.count, and dlc.txdate.

At tx=7409 all three mutable attributes were updated in a single transaction. For each one SingleValueUpsert staged a retraction of the old valkey (OP=0) and an assertion of the new valkey (OP=1) in the same tx. This is the immutable update pattern used for cardinality-one attributes: the old value is retracted (op=0) and the new value asserted (op=1) in the same transaction, preserving complete history.

aidattributetxvalkeyOPresolved value
1005sandbox.dlc.id7407K3ED.018828+042
1006sandbox.dlc.checkup7407K3EE.018829+Dilithium Crystals on 1st January 2013 @en
1006sandbox.dlc.checkup7409K3EE.018829-Dilithium Crystals on 1st January 2013 @en
1006sandbox.dlc.checkup7409K3EE.018831+Dilithium Crystals on 1st February 2013 @en
1007sandbox.dlc.count7407K3EF.01882A+100
1007sandbox.dlc.count7409K3EF.01882A-100
1007sandbox.dlc.count7409K3EF.018832+250
1008sandbox.dlc.txdate7407K3F0.01882B+2013-01-01
1008sandbox.dlc.txdate7409K3F0.01882B-2013-01-01
1008sandbox.dlc.txdate7409K3F0.018833+2013-02-01
DO PE^api("042",dlcid)

2026-06-30T20:42:06.169737 | API | DEBUG | GetEID: resolved via aid=1005 val=042

======
042
======
  6557d1f58f6f65apmlu8  sandbox.dlc.id           042
  6557d1f58f6f65apmlu8  sandbox.dlc.checkup      Dilithium Crystals on 1st January 2013 @en
  6557d1f58f6f65apmlu8  sandbox.dlc.count        100
  6557d1f58f6f65apmlu8  sandbox.dlc.txdate       2013-01-01
  • dlcid (aid=1005) has only one entry across all transactions, it is a unique-insert attribute and was never updated
  • At tx=7409 each updated attribute carries both a ( - ) for the old value and a ( + ) for the new value
    old and new valkeys coexist within the same tx, making the transition fully auditable
  • PE reading the same entity shows only the rows marked ( + ) at the highest tx per attribute — the current active state