Vercy · additive profile

11 fields to add to the memory you already run.

The overlay does not replace a memory store. It names the fields the benchmarks found to be load-bearing and says where each one goes in the stores people already run.

Why an overlay and not a format

The collaborative benchmark set out to test whether governance belongs inside the memory record or in a layer beside it. It found no difference: the fields inside the record scored 95.2%, the same graph with a separate governance catalogue 93.5%, and a team wiki carrying the same facts in prose 96.8%, every pairwise comparison at p = 1.00. Where the information sits does not matter.

What did matter was whether it exists at all. Adding governance to a bi-temporal graph took it from 77.4% to 93.5%, p = 0.039. So the useful thing to publish is not another store or another serialisation. It is the field set, expressed so that it can be added to a graph, a vector memory, a catalogue, a wiki or a table without moving any data.

The fields

Each field is listed with the capability it carries and the measured difference between having it and not having it, read from the published result of the study that measured it. PDB is the personal dimension benchmark, CMB the collaborative memory benchmark.

FieldLevelRequirementWhat it isMeasured without → with
record_id1MUSTA stable identifier for the record itself, short enough to be written by hand.0.0% → 100.0% (CMB)
valid_from1MUSTThe date from which the statement was true. Not the date it was captured.0.0% → 100.0% (PDB)
valid_to1MUSTThe date after which it stopped being true. The field must be present; null means it still holds.20.0% → 100.0% (PDB)
source2MUSTWhere the statement came from, as an identifier that can be followed.33.3% → 100.0% (PDB)
concept_owner2MUSTThe single party accountable for what the concept means. One per concept.80.0% → 100.0% (CMB)
owner_role2SHOULDThe accountable role inside that party, so a request reaches a person.68.8% → 100.0% (CMB)
conflict_policy2MUSTOne rule, stated once per store, for choosing between records that cover the same date and disagree.33.3% → 100.0% (CMB)
applies_to2MUST on any record that states a ruleThe question classes the rule governs. A rule with no stated scope silently governs more than its author meant.58.3% → 70.8% (SGB)
does_not_apply_to2MUST on any record that states a ruleThe question classes the rule explicitly does not govern. Written separately because a reader cannot infer the negative from the positive.79.2% → 83.3% (SGB)
release_to3MUST where any record is restrictedThe parties permitted to read this record. Absence of the field is not permission.59.1% → 100.0%; critical over-shares 2 → 0 (CMB)
supersedes3SHOULDThe identifier of the record this one replaces, so an update never has to be expressed by editing history.0.0% → 66.7% (PDB)
expected_concepts-EXPERIMENTALA register of the concepts the store is meant to hold, so that a concept missing altogether becomes detectable. Tested once; see below.33.3% → 100.0% (R5)

Three levels

The levels are ordered by what each one unlocks, so a store can adopt the overlay in stages and know what it has bought at each step.

Level 1 - time and identity
Answers questions about any date, and lets an update name what it replaces.
Level 2 - provenance and authority
Resolves disagreement by rule instead of by guess, and routes a change request to the party accountable for it.
Level 3 - disclosure
Decides what may cross a boundary without either leaking or over-refusing.

Where each field goes

Five target shapes plus the native one. A cell in amber is a field the target has no home for, and the cell says how to add it. Everything else is already there under another name.

FieldBi-temporal graphVector memoryData catalogueWiki or documentsRelational tableVercy Dimension
record_idedge uuidmemory idterm or asset identifiera short tag written in the line, for example [D-102]primary keyid
valid_fromvalid_atadd: metadata field, distinct from the created-at timestampadd: usually only the asset has versions, the statement does notstated in the sentencedate columnvalid_from
valid_toinvalid_atadd: metadata fieldadd: samestated in the sentencenullable date columnvalid_to
sourcethe episodic node the edge was extracted frommetadata fieldlineage link to the source assetnamed in the sentenceforeign key to a source tablesource
concept_owneradd: OWNED_BY edge from the entity to a party nodeadd: metadata fieldowner field, nativea page listing who owns whatforeign key to a party tableconcept_owner
owner_roleadd: role attribute on that OWNED_BY edgeadd: metadata fieldsteward or accountable role, nativethe role named on that pagecolumn on the party tableowner_role
conflict_policyadd: one graph-level property, or a single policy nodeadd: one pinned memory, or application configurationadd: a policy document linked from the glossarya page stating how disagreements are settledone row in a policy table, referenced by the storeconflict_policy
applies_toadd: attribute on the rule edge, or SCOPES edges to entity classesadd: metadata list on the memory holding the rulepolicy scope, native in most cataloguesthe sentence says which questions the rule governsjoin table of rule to question classapplies_to
does_not_apply_toadd: EXCLUDES edges from the rule edgeadd: metadata list, kept separate from applies_toadd: catalogues usually state inclusion onlya second sentence saying what it does not governthe same join table with an excluded flagdoes_not_apply_to
release_toadd: VISIBLE_TO edges, or a list attribute on the fact edgeadd: metadata list, applied as a retrieval filterclassification and purpose policies, nativestated in the line that holds the restricted statementjoin table of record to partyrelease_to
supersedesadd: SUPERSEDES edge between fact edgesadd: metadata field holding the prior memory idterm version history, nativethe tag of the superseded line, named in the new lineself-referencing foreign keysupersedes
expected_conceptsadd: entity nodes marked as expected but unpopulatedadd: a separate register, not a memoryadd: a list of required termsa checklist pagea table of required conceptsnot yet in the specification

The cells use each target system's own vocabulary and are left in English in every language, so that this table, profile.yaml and mappings.csv say the same thing. The wiki column is not a fallback: in the collaborative benchmark a wiki carrying these fields in ordinary sentences scored 96.8%, the highest of any representation tested.

Four things implementers get wrong

What this rests on

Three benchmarks, 1,926 model calls, one model family, tools disabled, and one authored world per study. The effect sizes above are from reasoning over records held in context; retrieval, ranking and ingestion were out of scope, and they are what several memory products consider their main contribution. The expected_concepts field is a hypothesis drawn from a measured blind spot, not a result: no study has tested it. Every number links back to a published raw run.

Recording a change

Both benchmarks produced the correct new value on every scenario and the wrong boundary date on a third to a fifth of them. The fix is not a better prompt but a narrower operation: write one new record, give it the date the new statement begins, name the record it supersedes, and leave the superseded record untouched.

superseded record, left untouched:
{
  "record_id": "D-802",
  "concept": "data_retention",
  "value": "customer records are kept for five years after the contract ends",
  "valid_from": "2026-06-01",
  "valid_to": null,
  "source": "LEG-POL-04",
  "concept_owner": "legal",
  "supersedes": "D-801"
}

new record:
{
  "record_id": "D-806",
  "concept": "data_retention",
  "value": "customer records are kept for three years after the contract ends",
  "valid_from": "2026-10-01",
  "valid_to": null,
  "source": "LEG-POL-06",
  "concept_owner": "legal",
  "supersedes": "D-802"
}

The end of a superseded interval is derived at read time, never written: a record is in force on a date when it covers that date and nothing superseding it began on or before it. Editing the old record, or computing its end date by hand, is exactly where the measured errors occurred.

The one field that was a hypothesis, and its test

expected_concepts was published as a proposal drawn from a measured blind spot: in the semantic grounding benchmark a definition absent from the catalogue altogether was the only gap that neither prose nor structure ever found. A register naming the concepts a store is meant to hold turns that absence into something to point at. That was untested when it was published. It has now been tested, in 60 calls over the same deficient catalogue with and without the register.

MeasureWithout the registerWith it
detecting the concept absent altogether33.3%100.0%
detecting any of the six planted gaps83.3%100.0%
false alarms on four questions with no gap8.3%8.3%

The field works on the case it was designed for, and the control that mattered held: a register that made the agent invent gaps would have been worse than none, and false alarms did not move. But only two of the six gaps changed, so the exact sign test over the family is p = 0.5. One small experiment does not make a requirement, so the field stays EXPERIMENTAL. The raw run is published beside the profile.

Paying less context for the same fields

The dimension was the largest context in both later studies and tied on accuracy, so the overlay should not cost twice the context to say the same thing. A fixed field order in one line per record removes most of that cost. The figures below are measured at build time on the published reference store, not asserted.

SerialisationCharactersSaving
one JSON object per line6,064-
compact line form1,86069.3%
# record_id|valid_from|valid_to|source|concept_owner|owner_role|supersedes|release_to|value
D-101|2025-01-01|2026-03-31|FIN-POL-04|finance|Head of Finance

The second half of the saving is selection. In the assembly track of the personal dimension benchmark an agent asked to choose the records a question needs recalled every needed record, chose 1.2 records out of 41, and cut the supplied context from 10,332 to 473 characters with no measurable change in accuracy, p = 0.34. The reduction is measured; a gain in accuracy is not, and should not be claimed.

Check a store against the levels

The checker takes a JSON array or one record per line, and a mapping from your own field names to the overlay roles. It reports the highest level the store satisfies and names the records that failed each requirement. It exits non-zero below level 1, so it fits a build.

python check.py store.jsonl
python check.py store.jsonl --map record_id=uuid,valid_from=valid_at,valid_to=invalid_at,source=episode

Two fixtures are published beside it. The reference store reaches level 3. The same records rendered as bi-temporal fact edges reach level 1 and report exactly what the collaborative benchmark found missing: no concept owner and no conflict policy.

profile.yamlmappings.csvcheck.pyreference storethe register experimentThe studies behind itThe specification