iterion

← Documentation index · ← BaaS overview

Memory and knowledge spaces

Audience. Bot authors who write to memory (memory_read / memory_write / memory_list), org admins enforcing a quota on shared knowledge, and operators wiring multi-tenant isolation.

Memory in iterion is a per-org tree of markdown documents — the substrate the cross-run “what did we learn” / “where did we leave off” loop runs on. The session-continuity skill (bots/whats-next/skills/session-continuity.md) is the canonical consumer.

Visibilities and what scopes them

A space is addressed by a SpaceRef (pkg/knowledge/scope.go:SpaceRef). The Visibility is the primary sharing axis; the other fields qualify it. Validation is enforced everywhere the ref crosses an untrusted boundary (REST handler, FS adapter, Mongo store) so a stray ?project= can’t escape the tree.

Visibility Shared across Required qualifiers Default sub-cap
private one run 64 MiB
bot every run of one bot in one project ProjectID + BotID 256 MiB
project every bot in one project (the cross-bot inbox) ProjectID 256 MiB
cross_project every project in one org 512 MiB
user one user across projects UserID 128 MiB
org every bot / run / project in one org 1 GiB
global the whole iterion instance (read-only catalogue) 0 (not writable through org path)

A space’s identity is v1:<visibility>:<tenant>:<project>:<bot>:<user>:<name> — deterministic; equal refs always produce equal ids (pkg/knowledge/scope.go:SpaceRef.ID).

Quotas

Two levels, both enforced at write:

DefaultMaxDocumentSize caps any one markdown document at 2 MiB (pkg/knowledge/quota.go).

GET /api/teams/{id}/usage surfaces the org’s memory_used_bytes against effective_memory_quota_bytes for the org admin; the per-space write CAS is what actually blocks an over-budget write.

REST surface

Method Path Auth Purpose
GET /api/memory/usage member {used_bytes, quota_bytes} for one space
GET /api/memory/docs member List documents (optional ?dir=)
GET /api/memory/doc member Read (?path=)
PUT /api/memory/doc member (super-admin for visibility=global) Write
DELETE /api/memory/doc member (super-admin for global) Delete
GET /api/memory/export member Tarball export of the space
POST /api/memory/import member (super-admin for global; optional ?strategy=) Tarball import

Query params resolve the space:

Param Required when Meaning
name always space name (single segment, no /, no ..)
visibility optional (default project) one of the values above
bot visibility=bot bot id
project visibility ∈ {bot, project} encoded project key (store.EncodeWorkDirKey of the workspace root)

Tenant + user are taken from the identity on the request — never a query param — so a member can’t read another org’s memory by editing the URL (pkg/server/memory_routes.go:memoryRef). Cross-tenant isolation is the contract the cloud (Mongo) adapter fail-closes on.

visibility=global is instance-wide (no tenant scoping); a write or import there requires super-admin in cloud mode — otherwise any authenticated member could pollute or wipe another org’s shared catalogue. Local single-tenant mode (no identity store) treats every write as allowed.

Doc path safety: the path is relative, no .. segments, no NUL byte, no absolute prefix. The same ValidateDocPath guard runs at the REST boundary and inside the FS adapter so the rule holds everywhere (pkg/knowledge/scope.go:ValidateDocPath).

Export / import

GET /api/memory/export streams a gzipped tarball of the space; the client gets Content-Disposition: attachment; filename="memory-export.tar.gz".

POST /api/memory/import decompresses and writes back; the ?strategy= query param picks a merge strategy from knowledge.ImportStrategy. Use the export → import pair to migrate a space between orgs (or environments).

How bots use memory

The canonical consumer is the session-continuity skill shipped in the whats-next bundle (bots/whats-next/skills/session-continuity.md). It exposes three tools that every catalog bot can use:

The skill ships per-bundle (not per-instance) so each bot’s authored scope is part of the bundle it lives in — see bundles.md → Resource resolution for the workspace-mirror mechanism.

Tenant isolation

Multi-tenant safety lives on three boundaries:

  1. REST: the handler stamps the tenant from the JWT/PAT identity onto the SpaceRef; query params can only override project, name, bot, visibility. Cross-tenant reads are not expressible.
  2. Cloud Mongo adapter: every document carries the full SpaceRef.ID() (which includes the tenant); queries are tenant-stamped from the request ctx, and the adapter fail-closes when the ctx carries no tenant.
  3. Validate path traversal: SpaceRef.Validate rejects .., /, and \ in every qualifier and the document path (pkg/knowledge/scope.go).

visibility=global is the only space that deliberately crosses the tenant boundary; writes there are gated on IsSuperAdmin and produce an audit entry through the admin path.