You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Building a production email→expense agent on the reference implementation (Areev 1.2.1, AreevAI/areev#23–#29) surfaced a set of places where the spec either restricts a construct it never defines, stays silent where the implementation had to commit to semantics, or has a reachability hole with compliance consequences. Filing as one consolidated catch-up ticket per maintainer request; each section can be split out when picked up. Spec refs are OMS 1.6-draft / CAL 1.3 / SML 1.1 as of openmemoryspec/oms@HEAD.
1. Saved queries are restricted four times, defined zero times
CAL §8.14.3, §8.16.1, §8.17 and CAL-E125 all constrain what may appear "inside saved-query bodies", and OMS §8.12 makes query:<namespace>/<name> a valid Recommendation target_ref — but there is no DEFINE QUERY statement, no grammar production, no naming/parameterization/versioning rule, no DESCRIBE target, and CAL §1.3 declares "no persistent variables".
The reference implementation has now shipped the whole lifecycle: DEFINE QUERY "name"($params) [DESCRIPTION "…"] AS { body }, RUN "name"($p = v), DESCRIBE QUERIES, DROP QUERY, storage as host meta rows (qry:<name>) that replicate in bundles with latest-wins convergence, a define-time parse of the body with parameters standing in (AreevAI/areev#24), and a mandatory read-only verification pass. Ask: adopt this as the normative definition (or amend as needed), including: bodies are Tier-0-only, define/drop are admin-gated, definitions are host metadata not grains, and define-time validation MUST parse the body as it would run.
2. Templates have no identity to version
OMS §8.12 rule 4 requires summary.template_id to "reference a deterministic template" and makes template:<ns>/<name> a Recommendation target — but CAL §10.6/§10.8 give templates a bare 64-char name: no version, no supersession, no content address, and UNDEFINE is reserved (Appendix D) with no semantics. A Recommendation applied against template:acct/invoice_row cannot say which revision it changed or store an honest inverse. Ask: minimal template identity — at least an updated_at-style revision the audit trail can pin, ideally a content hash of the definition body; define DROP TEMPLATE/UNDEFINE semantics.
3. No mail/thread vocabulary
Events model LLM turns (role is a chat enum). There is no From/To/Cc/Subject/Message-ID/In-Reply-To/References vocabulary anywhere; threading is session_id + parent_message_id (§28.6). Every email-shaped agent invents its own context-map keys, which defeats portability of exactly the grains most worth porting. Ask: either (a) a registered mail: domain profile (Appendix A) — noting CAL's domain_prefix grammar is closed, so this needs a CAL minor — or (b) the smaller change: a first-class thread_id common field alongside session_id/run_id, plus a note mapping RFC 5322 identifiers onto Event fields.
4. Triggers have a declaration format but no execution contract
§27.6 defines trigger declarations (Observation grains, observer_type: "trigger:*", int: config) and stops. Nothing normative says what evaluates a declaration, how a firing becomes a grain, what idempotency/dedup a twice-delivered webhook gets, or how a trigger binds to a Workflow. The reference implementation is about to commit to semantics here (AreevAI/areev#26: one-shot host-invoked evaluation, connector subprocess contract, firing journaled as an Observation, binding = Workflow hash). Ask: specify the execution contract — even a minimal one: firing MUST be journaled, item ingestion MUST be idempotent on a declared dedup key, binding resolution rules. Also: register the "trigger:*" observer_type values in §24 (today they exist only in §27.6 prose).
5. Blob lifecycle and surfaces
Three related gaps:
cas:// is never defined — it appears once as an example URI in §7.1. The reference implementation treats cas://sha256:<64-hex> as normative (address = plaintext digest, stable across encrypted/plaintext stores, re-verified on read). Specify the scheme.
No blob operations in §28.4 — the operation table is grains-only. The implementation now ships put_blob/get_blob on CLI + bindings (Expose the CAS blob store beyond Rust: areev blob put|get, bindings AreevAI/areev#27), including a deliberate lock-free read path (a blob is immutable; its address is its checksum). Specify put_blob/get_blob and the locking expectation.
Erasure does not reach referenced blobs — FORGET SUBJECT and crypto-erasure act on grains; a subject's invoice PDF referenced via content_refs survives erasure of every grain referencing it, and the spec is silent. The implementation reclaims sole-referenced CAS attachments during subject erasure and reports blobs_reclaimed. Make that normative — this is a GDPR-grade hole, same severity class as the vault-row rule in §10.5.2.
6. Subject reachability for erasure/DSAR selection (compliance-grade)
Found as AreevAI/areev#23: a grain carrying a subject with no relation/object (an Event about an identity) reached no structural index, so FORGET SUBJECT / REPORT SUBJECT — which select through those indexes — missed it: the grain survived erasure and went undisclosed in a DSAR while the operation reported success. The spec defines the selector (FORGET SUBJECT <id>, CAL §8.14) but never states the reachability obligation. Ask: a conformance requirement that subject selection MUST reach every grain whose subject (and user_id, and partition-key derivatives) matches, regardless of grain type or the presence of relation/object — with a conformance test. Implementations should not be able to pass conformance while silently under-erasing.
7. Housekeeping (drive-by, same doc pass)
mg:step_action:<node_id> is used normatively in §8.4 but absent from the §8 / CAL §7.1 relation vocabularies — a conformant validator warns CAL-W001 on the spec's own relation.
SPECIFICATION.md header says 1.6-draft while the footer says "v1.5 revision"; SML 1.1 self-describes as "Part of OMS v1.5"; CONTRIBUTING.md references a non-existent oms-specification.md.
CAL §10.x: WITH progressive_disclosure(...) semantics shipped in the implementation (body-axis clipping at 40/80 chars, full adds Skill instructions/when_to_use) — worth capturing while defining, since §10.5's tier ladder is the same mechanism.
Context
Building a production email→expense agent on the reference implementation (Areev 1.2.1, AreevAI/areev#23–#29) surfaced a set of places where the spec either restricts a construct it never defines, stays silent where the implementation had to commit to semantics, or has a reachability hole with compliance consequences. Filing as one consolidated catch-up ticket per maintainer request; each section can be split out when picked up. Spec refs are OMS 1.6-draft / CAL 1.3 / SML 1.1 as of
openmemoryspec/oms@HEAD.1. Saved queries are restricted four times, defined zero times
CAL §8.14.3, §8.16.1, §8.17 and
CAL-E125all constrain what may appear "inside saved-query bodies", and OMS §8.12 makesquery:<namespace>/<name>a valid Recommendationtarget_ref— but there is noDEFINE QUERYstatement, no grammar production, no naming/parameterization/versioning rule, noDESCRIBEtarget, and CAL §1.3 declares "no persistent variables".The reference implementation has now shipped the whole lifecycle:
DEFINE QUERY "name"($params) [DESCRIPTION "…"] AS { body },RUN "name"($p = v),DESCRIBE QUERIES,DROP QUERY, storage as hostmetarows (qry:<name>) that replicate in bundles with latest-wins convergence, a define-time parse of the body with parameters standing in (AreevAI/areev#24), and a mandatory read-only verification pass. Ask: adopt this as the normative definition (or amend as needed), including: bodies are Tier-0-only, define/drop are admin-gated, definitions are host metadata not grains, and define-time validation MUST parse the body as it would run.2. Templates have no identity to version
OMS §8.12 rule 4 requires
summary.template_idto "reference a deterministic template" and makestemplate:<ns>/<name>a Recommendation target — but CAL §10.6/§10.8 give templates a bare 64-char name: no version, no supersession, no content address, andUNDEFINEis reserved (Appendix D) with no semantics. A Recommendation applied againsttemplate:acct/invoice_rowcannot say which revision it changed or store an honest inverse. Ask: minimal template identity — at least anupdated_at-style revision the audit trail can pin, ideally a content hash of the definition body; defineDROP TEMPLATE/UNDEFINEsemantics.3. No mail/thread vocabulary
Events model LLM turns (
roleis a chat enum). There is no From/To/Cc/Subject/Message-ID/In-Reply-To/References vocabulary anywhere; threading issession_id+parent_message_id(§28.6). Every email-shaped agent invents its owncontext-map keys, which defeats portability of exactly the grains most worth porting. Ask: either (a) a registeredmail:domain profile (Appendix A) — noting CAL'sdomain_prefixgrammar is closed, so this needs a CAL minor — or (b) the smaller change: a first-classthread_idcommon field alongsidesession_id/run_id, plus a note mapping RFC 5322 identifiers onto Event fields.4. Triggers have a declaration format but no execution contract
§27.6 defines trigger declarations (Observation grains,
observer_type: "trigger:*",int:config) and stops. Nothing normative says what evaluates a declaration, how a firing becomes a grain, what idempotency/dedup a twice-delivered webhook gets, or how a trigger binds to a Workflow. The reference implementation is about to commit to semantics here (AreevAI/areev#26: one-shot host-invoked evaluation, connector subprocess contract, firing journaled as an Observation, binding = Workflow hash). Ask: specify the execution contract — even a minimal one: firing MUST be journaled, item ingestion MUST be idempotent on a declared dedup key, binding resolution rules. Also: register the"trigger:*"observer_type values in §24 (today they exist only in §27.6 prose).5. Blob lifecycle and surfaces
Three related gaps:
cas://is never defined — it appears once as an example URI in §7.1. The reference implementation treatscas://sha256:<64-hex>as normative (address = plaintext digest, stable across encrypted/plaintext stores, re-verified on read). Specify the scheme.put_blob/get_blobon CLI + bindings (Expose the CAS blob store beyond Rust:areev blob put|get, bindings AreevAI/areev#27), including a deliberate lock-free read path (a blob is immutable; its address is its checksum). Specifyput_blob/get_bloband the locking expectation.FORGET SUBJECTand crypto-erasure act on grains; a subject's invoice PDF referenced viacontent_refssurvives erasure of every grain referencing it, and the spec is silent. The implementation reclaims sole-referenced CAS attachments during subject erasure and reportsblobs_reclaimed. Make that normative — this is a GDPR-grade hole, same severity class as the vault-row rule in §10.5.2.6. Subject reachability for erasure/DSAR selection (compliance-grade)
Found as AreevAI/areev#23: a grain carrying a
subjectwith no relation/object (an Event about an identity) reached no structural index, soFORGET SUBJECT/REPORT SUBJECT— which select through those indexes — missed it: the grain survived erasure and went undisclosed in a DSAR while the operation reported success. The spec defines the selector (FORGET SUBJECT <id>, CAL §8.14) but never states the reachability obligation. Ask: a conformance requirement that subject selection MUST reach every grain whosesubject(anduser_id, and partition-key derivatives) matches, regardless of grain type or the presence of relation/object — with a conformance test. Implementations should not be able to pass conformance while silently under-erasing.7. Housekeeping (drive-by, same doc pass)
mg:step_action:<node_id>is used normatively in §8.4 but absent from the §8 / CAL §7.1 relation vocabularies — a conformant validator warnsCAL-W001on the spec's own relation.oms-specification.md.WITH progressive_disclosure(...)semantics shipped in the implementation (body-axis clipping at 40/80 chars,fulladds Skillinstructions/when_to_use) — worth capturing while defining, since §10.5's tier ladder is the same mechanism.