The memory write entry point validates an entry, stores it through the selected provider, and updates the index under a shared lock. This excerpt shows the persistence contract, not a claim about later recall quality.
Inspect the source excerpt
def write(
name: str,
description: str,
type: str,
subject: str,
body: str,
provider: Provider | None = None,
) -> str:
"""Validate, store via provider, and append a MEMORY.md bullet.
Returns the stored path/id reported by the provider.
Raises:
ValueError: if `type` is not one of VALID_TYPES, or if `name`,
`description`, or `subject` is empty/whitespace.
MemoryCollisionError: re-raised from the provider when the resolved
location already exists.
MemoryAmbiguousSubjectError: re-raised from the provider when subject
resolution is ambiguous.
MemorySubjectNotFoundError: re-raised from the provider when subject
does not resolve to any PARA entity directory (and no alias
in `<vault>/.memory-aliases.yaml` redirects it to one).
"""
if type not in VALID_TYPES:
raise ValueError(
f"invalid type: {type!r}; expected one of {sorted(VALID_TYPES)!r}"
)
for field_name, val in (
("name", name),
("description", description),
("subject", subject),
):
if not val or not val.strip():
raise ValueError(f"{field_name} is required")
# The MEMORY.md bullet format embeds every field verbatim on a
# single line, with this shape:
# - [[<path>|<name>]] · type:T subject:S · <description>
# A field containing a character that conflicts with the format
# produces a bullet that the parser silently skips — put() succeeds
# but the entry never appears in list()/get() results.
#
# Reject the conflicting characters at the writer (the only
# supported entry point) so a malformed entry never reaches the
# index.
if any(c in name for c in "]|\r\n"):
raise ValueError(
f"name must not contain ']', '|', or newline characters "
f"(they break the [[path|name]] bullet link); got {name!r}"
)
if "\r" in description or "\n" in description:
raise ValueError(
f"description must not contain newline characters "
f"(bullets are one line each); got {description!r}"
)
if any(c.isspace() for c in subject):
raise ValueError(
f"subject must not contain whitespace; got {subject!r}"
)
if "\u00b7" in subject:
raise ValueError(
f"subject must not contain the index separator '\u00b7'; "
f"got {subject!r}"
)
provider = provider if provider is not None else _get_provider()
# Always source vault_root from the provider, not from the env, so an
# injected provider with a custom root keeps its index file and entry
# files in the same directory tree. Previously memory_writer pulled
# vault_root from MEMORY_VAULT_DIR independently, which silently
# misaligned index and storage when a caller passed a provider with
# a different root.
vault_root = Path(provider.root)
with memory_lock(vault_root, context="memory_writer.write"):
entry = Entry(
name=name,
description=description,
type=type,
subject=subject,
body=body,
)
path = provider.put(entry)
# Convert to a vault-relative path for the index. If the provider stored
# the entry outside vault_root (e.g. a test FilesystemProvider rooted
# elsewhere), fall back to the raw path the provider returned.
try:
rel_path = Path(path).relative_to(vault_root).as_posix()
except ValueError:
rel_path = path
index.append(vault_root, name, type, subject, rel_path, description)
return path