Skip to content

Spec catch-up with the reference implementation: saved queries, template identity, mail/thread vocabulary, trigger execution, blob lifecycle, subject reachability #12

Description

@sathish-mg

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-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 blobsFORGET 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions