Spec-02-Scopes-and-ACL
What this spec defines
The supported visibility boundary for facts: coarse FactScope
enforcement plus the basic Memory Garden ACL layer retained in the
v0.9.0a1 protocol line.
Extraction status
This file contains the ADR-010 prose extraction for scope enforcement and basic Memory Garden ACL behavior. It intentionally does not include API-key credential shape, peer-token signing, federation replication rules, quarantine garden moderation, advanced Memory Garden ACL behavior, or HTTP route details. Those belong to their own component or experimental specs.
Legacy section labels from archived sources are normalized to the
current v0.9.0a1 protocol line. Historical wording remains
available in spec/archive/evolution/ and spec/EVOLUTION.md.
Source map
stigmem-spec-v0.8-draft.md §3.4stigmem-spec-v1.0.md §17garden_acl.py + test_gardens.pyScope enforcement
Scope is enforced at read and write time.
Cross-scope queries are additive: a caller may query across the scopes it is authorized to read, but authorization must be evaluated per scope before any fact is returned.
The supported coarse scopes are defined by FactScope in
Spec-01-Fact-Model:
local | team | company | public
Facts without a garden use scope-only access control. Facts with a
garden_id must also pass the Memory Garden ACL rules in this spec.
Federation boundary
Federation scope enforcement is defined in the federation-trust component, but this spec owns the basic invariant:
No over-scope replication
Nodes MUST NOT replicate facts whose scope is not permitted by the active peer relationship.
Reject over-scope inbound
Nodes MUST reject inbound facts whose scope exceeds what the peer is authorized to write.
Per-hop evaluation
Scope enforcement is evaluated per hop in multi-node topologies.
The detailed peer declaration, token, and re-federation rules live
in Spec-05-Federation-Trust.
Memory Garden primitive
The coarse scope model is intentionally small. A Memory Garden adds a named, ACL-controlled partition inside a scope, for cases where a subset of principals needs shared access without exposing those facts to every reader of the broader scope.
A garden is represented by a Garden record and a set of
GardenMember records:
Garden {
id: UUID
garden_id: URI
slug: string
name: string
scope: FactScope
description: string?
created_by: URI
created_at: ISO 8601 UTC
}
GardenRole = "admin" | "writer" | "reader"
GardenMember {
garden_id: UUID
entity_uri: URI
role: GardenRole
added_by: URI
added_at: ISO 8601 UTC
}
garden_id URIs use this shape:
stigmem://{node_authority}/garden/{slug}
A garden's scope is fixed at creation time. All facts tagged with that garden MUST use the same scope.
Write access
Garden ACL is checked in addition to normal scope enforcement.
garden_id absentadmin/writerreaderWriters and admins retract garden-tagged facts through the normal
immutable retraction pattern: assert a new fact for the same
(entity, relation, scope) with confidence=0.0 and the same
garden boundary.
Read access
A garden-tagged fact is returned only when the caller:
- Passes normal scope enforcement.
- Holds at least
readerrole in the garden.
Garden enumeration through global queries MUST be prevented.
When a caller queries by explicit garden_id, non-members receive
HTTP 403. When a caller performs a broader query without a
garden_id filter, garden-tagged facts from gardens the caller
cannot read MUST be excluded from the result set. Single-fact reads
MUST enforce the same ACL: a caller who can guess or obtain a fact
id MUST NOT be able to bypass garden membership checks.
Admin operations
admin.Deleting a basic garden removes the garden container. It MUST NOT delete the facts that were tagged with that garden.
Relationship to scope
Gardens and scopes are layered controls:
Scope: local | team | company | public
Garden: named subset of principals within one scope
A garden's scope declares the coarse visibility tier of all facts in the garden. Garden ACL can only narrow access relative to the scope; it cannot broaden it.
Company-scoped garden fact
Not visible to every company-scope reader; the caller must also be a garden member.
Public-scoped garden fact
Remains garden-controlled. Implementations MUST NOT use public scope alone as authorization to expose garden-tagged facts.
Untagged facts
Facts without garden_id are unaffected by garden ACL and continue to use scope-only enforcement.
Reserved garden namespace
The garden: relation prefix is reserved for garden membership
metadata. The node writes membership metadata automatically when
callers manage gardens. System-authored garden membership facts use
source="system:stigmem" so attestation and provenance checks can
distinguish operator-managed membership from agent-authored
assertions.
Out of scope
This spec does not define:
Garden CRUD route shape
Belongs in Spec-03-HTTP-API.
Peer declarations / tokens
Belong in Spec-05-Federation-Trust.
Capability token grants
Belong in Spec-06-Capability-Tokens.
Quarantine moderation
Belongs in Spec-08-Quarantine-Garden.
Advanced Memory Garden ACL
Experimental: Spec-X5-Memory-Garden-Advanced-ACL.