← Memova.aiCONTENT HISTORY

Update to Memova.ai

Snapshot Oct 24, 2026 · 13:10 UTC · version 1.15.1

WHAT CHANGED

Package or technical metadata updated

Package or technical metadata updated

Observed in package metadata. These changes alone do not establish a new customer-facing feature.

Save Memova.ai and check future changes in Following.

Up to 3 plugins free · no card required.

All fields and original values.

These are saved file metadata. Open a changed file to read its text edits.

Package file

Before

Sep 30, 2026 · 23:00 UTC

333caf4b33faceae5e71a169c696a070f4ffbcf5392c83f22704ce8a8b058311

After

Oct 24, 2026 · 13:10 UTC

af9ff37fc68dfba75882c0f49b53ceb412fbd6924d3e97fe08efee3dedaffe77

Package file

Before

Sep 30, 2026 · 23:00 UTC

127

After

Oct 24, 2026 · 13:10 UTC

98

Package file

Before

Sep 30, 2026 · 23:00 UTC

b09aeecc839ac6fbdaffa93c985edcda36eae4a10cd319f4d2e306b772f83e4b

After

Oct 24, 2026 · 13:10 UTC

4d721d3b50a321c7069b5ab068b3709adbb9fb2fcbb57df56e857d7290ec7a5a

Package file

Before

Sep 30, 2026 · 23:00 UTC

1223

After

Oct 24, 2026 · 13:10 UTC

10908

Compare saved observations

Download comparison JSON

Changed files

Choose a file to see its text changes. Binary or large files show metadata only.

.app.json →

.codex-plugin/plugin.json →

.mcp.json →

assets/icon.svg →

assets/logo.svg →

contracts/resource_access_plugin_binding_v1.json →

contracts/upstream/memova_resource_access_v1.json →

menu_catalog.json →

scripts/agent_archive.py →

scripts/check_menu_catalog.py →

scripts/ensure_mcp_login.py →

scripts/kb_setup_reminder.py →

scripts/mcp_connection_auth.py →

scripts/mcp_credential_store.py →

scripts/memova_menu.py →

scripts/validate_resource_access_contract.py →

scripts/version_check.py →

skills/memova-agent-archive/SKILL.md →

skills/memova-agent-archive/agents/openai.yaml →

skills/memova-connect/SKILL.md →

skills/memova-connect/agents/openai.yaml →

skills/memova-explicit-import/SKILL.md →

skills/memova-explicit-import/agents/openai.yaml →

skills/memova-explicit-import/scripts/preview_selected_import.py →

skills/memova-knowledge/SKILL.md →

skills/memova-knowledge/agents/openai.yaml →

skills/memova-menu/SKILL.md →

skills/memova-menu/agents/openai.yaml →

skills/memova-personal-manual/SKILL.md →

skills/memova-personal-manual/agents/openai.yaml →

skills/memova-personal-manual/references/local-artifacts.md →

skills/memova-personal-manual/scripts/prepare_personal_manual.py →

skills/memova-resource-access/SKILL.md →

skills/memova-resource-access/agents/openai.yaml →

skills/memova-vault-diagnose/SKILL.md →

skills/memova-vault-diagnose/agents/openai.yaml →

skills/memova-vault-setup/SKILL.md →

skills/memova-vault-setup/agents/openai.yaml →

skills/memova-vault-setup/scripts/create_memova_vault.py →

skills/memova-vault-setup/scripts/diagnose_memova_vault.py →

skills/memova-vault-setup/scripts/find_vault_locations.py →

skills/memova-vault-setup/scripts/inspect_vault.py →

skills/memova-vault-setup/scripts/memova_vault_lib.py →

skills/memova-vault-setup/scripts/setup_fixture_harness.py →

skills/memova-vault-setup/scripts/validate_memova_vault.py →

skills/memova-workflow/SKILL.md →

skills/memova-workflow/agents/openai.yaml →

scripts/agent_archive.py

− removed · + added

--- before
+++ after
@@ -0,0 +1,412 @@
+#!/usr/bin/env python3
+"""Local, consent-aware manifest for Memova Agent output archiving.
+
+The helper never enumerates a repository or Codex history. Scheduled runs may only inspect exact
+source paths previously added to this Plugin-owned manifest.
+"""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import os
+import re
+import shutil
+import sys
+import tempfile
+import uuid
+from datetime import UTC, datetime
+from pathlib import Path
+from typing import Any
+
+SCHEMA_VERSION = "memova_agent_archive_local_v1"
+MCP_SCHEMA_VERSION = "memova_agent_archive_v1"
+MAX_BYTES = 500_000
+ALLOWED_SUFFIXES = {
+    ".md": "text/markdown",
+    ".markdown": "text/markdown",
+    ".html": "text/html",
+    ".htm": "text/html",
+    ".txt": "text/plain",
+}
+BLOCKED_DIRS = {
+    ".git",
+    ".hg",
+    ".svn",
+    ".cache",
+    ".pytest_cache",
+    ".mypy_cache",
+    ".ruff_cache",
+    "node_modules",
+    "vendor",
+    "dist",
+    "build",
+    "coverage",
+    "logs",
+    "tmp",
+    "temp",
+    "__pycache__",
+}
+BLOCKED_NAMES = {
+    ".env",
+    "credentials",
+    "credentials.json",
+    "id_rsa",
+    "id_ed25519",
+    "secrets.json",
+}
+SECRET_PATTERNS = (
+    re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----", re.I),
+    re.compile(r"(?i)\bbearer\s+[A-Za-z0-9._~+/=-]{12,}"),
+    re.compile(r"\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{16,}\b"),
+    re.compile(r"\b(?:gh[opusr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b"),
+    re.compile(r"\bxox[baprs]-[A-Za-z0-9-]{16,}\b"),
+    re.compile(r"\b(?:AKIA|ASIA)[A-Z0-9]{16}\b"),
+    re.compile(
+        r"(?i)\b(?:password|passwd|pwd|api[_-]?key|access[_-]?token|refresh[_-]?token|"
+        r"client[_-]?secret|secret)\b\s*[:=]\s*['\"]?[^\s,'\";]{4,}"
+    ),
+)
+
+
+class ArchiveError(RuntimeError):
+    pass
+
+
+def _state_path() -> Path:
+    override = os.environ.get("MEMOVA_AGENT_ARCHIVE_STATE")
+    if override:
+        return Path(override).expanduser().resolve()
+    return Path.home() / ".memova" / "codex-agent-archive.json"
+
+
+def _empty_state() -> dict[str, Any]:
+    return {
+        "schema_version": SCHEMA_VERSION,
+        "mode": "explicit_only",
+        "vault_root": None,
+        "authorized_outputs": {},
+        "asked_task_ids": [],
+        "updated_at": None,
+    }
+
+
+def _load_state() -> dict[str, Any]:
+    path = _state_path()
+    if not path.exists():
+        return _empty_state()
+    data = json.loads(path.read_text(encoding="utf-8"))
+    if data.get("schema_version") != SCHEMA_VERSION:
+        raise ArchiveError("Unsupported Agent archive local-state schema.")
+    return data
+
+
+def _save_state(state: dict[str, Any]) -> None:
+    path = _state_path()
+    path.parent.mkdir(parents=True, exist_ok=True)
+    state["updated_at"] = datetime.now(UTC).isoformat()
+    handle, temp_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
+    try:
+        with os.fdopen(handle, "w", encoding="utf-8") as stream:
+            json.dump(state, stream, ensure_ascii=False, sort_keys=True, indent=2)
+            stream.write("\n")
+        os.chmod(temp_name, 0o600)
+        os.replace(temp_name, path)
+    finally:
+        if os.path.exists(temp_name):
+            os.unlink(temp_name)
+
+
+def _sha(data: bytes) -> str:
+    return hashlib.sha256(data).hexdigest()
+
+
+def _validate_source(path: Path) -> tuple[bytes, str]:
+    path = path.expanduser().resolve()
+    if not path.is_file():
+        raise ArchiveError("Authorized output path is not a regular file.")
+    if path.name.casefold() in BLOCKED_NAMES:
+        raise ArchiveError("Credential and environment files cannot be archived.")
+    if any(part.startswith(".") or part.casefold() in BLOCKED_DIRS for part in path.parts):
+        raise ArchiveError("Hidden, dependency, build, cache, temporary, and log paths are excluded.")
+    content_type = ALLOWED_SUFFIXES.get(path.suffix.casefold())
+    if content_type is None:
+        raise ArchiveError("Only Markdown, HTML, and plain-text final outputs are supported.")
+    data = path.read_bytes()
+    if not data or len(data) > MAX_BYTES or b"\x00" in data:
+        raise ArchiveError("Output must be non-empty UTF-8 text no larger than 500000 bytes.")
+    try:
+        text = data.decode("utf-8")
+    except UnicodeDecodeError as exc:
+        raise ArchiveError("Output must be UTF-8 text.") from exc
+    if any(pattern.search(text) for pattern in SECRET_PATTERNS):
+        raise ArchiveError("Output appears to contain Restricted Data; filter it before archiving.")
+    lowered = text.casefold()
+    if "<!-- memova-" in lowered or "<!--memova-" in lowered or "memova-link:v1" in lowered:
+        raise ArchiveError("Output contains a reserved Memova control marker.")
+    return data, content_type
+
+
+def _configured_root(state: dict[str, Any]) -> Path:
+    raw = state.get("vault_root")
+    if not isinstance(raw, str) or not raw:
+        raise ArchiveError("Configure the bound Memova Knowledge Base path first.")
+    root = Path(raw).expanduser().resolve()
+    if not root.is_dir():
+        raise ArchiveError("Configured Memova Knowledge Base path is unavailable.")
+    destination = root / "projects" / "Uncategorized"
+    destination.mkdir(parents=True, exist_ok=True)
+    return root
+
+
+def _manifest_key(path: Path) -> str:
+    return hashlib.sha256(str(path.expanduser().resolve()).encode("utf-8")).hexdigest()
+
+
+def _copy_authorized(
+    *,
+    state: dict[str, Any],
+    source: Path,
+    data: bytes,
+    entry: dict[str, Any],
+) -> Path:
+    root = _configured_root(state)
+    destination = root / str(entry["relative_path"])
+    destination.parent.mkdir(parents=True, exist_ok=True)
+    current_hash = _sha(destination.read_bytes()) if destination.exists() else None
+    expected_hash = entry.get("local_sha256")
+    if current_hash is not None and expected_hash is None:
+        if current_hash != _sha(data):
+            raise ArchiveError("Uncategorized destination already exists with different content.")
+    elif current_hash is not None and current_hash not in {expected_hash, _sha(data)}:
+        raise ArchiveError("Uncategorized destination changed outside the authorized workflow.")
+    handle, temp_name = tempfile.mkstemp(prefix=f".{destination.name}.", dir=destination.parent)
+    os.close(handle)
+    try:
+        shutil.copyfile(source, temp_name)
+        os.replace(temp_name, destination)
+    finally:
+        if os.path.exists(temp_name):
+            os.unlink(temp_name)
+    entry["local_sha256"] = _sha(data)
+    return destination
+
+
+def _request(
+    *,
+    state: dict[str, Any],
+    source: Path,
+    task_id: str,
+    source_reference: str,
+    title: str | None,
+    source_kind: str,
+    archive_mode: str,
+    authorize: bool,
+) -> dict[str, Any]:
+    data, content_type = _validate_source(source)
+    key = _manifest_key(source)
+    entries = state["authorized_outputs"]
+    entry = entries.get(key)
+    persistent_authorization = archive_mode in {"always_auto_save", "scheduled"}
+    if entry is None:
+        if not authorize:
+            raise ArchiveError("This exact output has not been authorized for Memova archiving.")
+        entry = {
+            "source_path": str(source.expanduser().resolve()),
+            "stable_node_id": str(uuid.uuid4()),
+            "relative_path": f"projects/Uncategorized/{source.name}",
+            "persistent_authorization": persistent_authorization,
+            "last_synced_sha256": None,
+            "local_sha256": None,
+        }
+        entries[key] = entry
+    elif archive_mode == "scheduled" and not entry.get("persistent_authorization"):
+        raise ArchiveError("Scheduled runs require a previously authorized manifest entry.")
+    elif authorize and persistent_authorization:
+        entry["persistent_authorization"] = True
+    destination = _copy_authorized(state=state, source=source, data=data, entry=entry)
+    entry.update(
+        {
+            "source_task_id": task_id,
+            "source_reference": source_reference,
+            "source_kind": source_kind,
+            "content_type": content_type,
+            "current_sha256": _sha(data),
+            "updated_at": datetime.now(UTC).isoformat(),
+        }
+    )
+    _save_state(state)
+    idempotency = hashlib.sha256(
+        f"{entry['stable_node_id']}:{_sha(data)}:{source_reference}".encode("utf-8")
+    ).hexdigest()
+    return {
+        "tool": (
+            "import_codex_task_markdown"
+            if source_kind == "codex_task_markdown"
+            else "import_agent_file"
+        ),
+        "arguments": {
+            "schema_version": MCP_SCHEMA_VERSION,
+            "stable_node_id": entry["stable_node_id"],
+            "idempotency_key": idempotency,
+            "source_kind": source_kind,
+            "source_task_id": task_id,
+            "source_reference": source_reference,
+            "title": (title or source.stem)[:255],
+            "relative_path": entry["relative_path"],
+            "content_type": content_type,
+            "content": data.decode("utf-8"),
+            "content_sha256": _sha(data),
+            "archive_mode": archive_mode,
+            "user_authorized": True,
+            "authorized_manifest_entry": bool(entry.get("persistent_authorization")),
+            "current_task_selected": source_kind == "codex_task_markdown",
+        },
+        "local_destination": str(destination),
+    }
+
+
+def command_configure(args: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    root = Path(args.vault_root).expanduser().resolve()
+    if not root.is_dir():
+        raise ArchiveError("Knowledge Base root must already exist and be a directory.")
+    (root / "projects" / "Uncategorized").mkdir(parents=True, exist_ok=True)
+    state["vault_root"] = str(root)
+    state["mode"] = args.mode
+    _save_state(state)
+    return {"status": "configured", "vault_root": str(root), "mode": args.mode}
+
+
+def command_prepare(args: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    mode = args.mode or state.get("mode") or "explicit_only"
+    if args.scheduled:
+        mode = "scheduled"
+    if mode in {"explicit_only", "ask_each_time"} and not args.authorize:
+        raise ArchiveError("This archive mode requires adjacent user authorization.")
+    return _request(
+        state=state,
+        source=Path(args.source),
+        task_id=args.task_id,
+        source_reference=args.source_reference,
+        title=args.title,
+        source_kind=args.source_kind,
+        archive_mode=mode,
+        authorize=args.authorize or mode == "always_auto_save",
+    )
+
+
+def command_scan(_: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    requests = []
+    for entry in list(state["authorized_outputs"].values()):
+        if not entry.get("persistent_authorization"):
+            continue
+        source = Path(str(entry["source_path"]))
+        try:
+            data, _content_type = _validate_source(source)
+        except ArchiveError as exc:
+            requests.append({"source_path": str(source), "status": "blocked", "reason": str(exc)})
+            continue
+        if _sha(data) == entry.get("last_synced_sha256"):
+            continue
+        try:
+            requests.append(
+                _request(
+                    state=state,
+                    source=source,
+                    task_id=str(entry.get("source_task_id") or "scheduled-authorized-output"),
+                    source_reference=str(entry.get("source_reference") or f"file://{source}"),
+                    title=None,
+                    source_kind=str(entry.get("source_kind") or "agent_file"),
+                    archive_mode="scheduled",
+                    authorize=False,
+                )
+            )
+        except ArchiveError as exc:
+            requests.append({"source_path": str(source), "status": "blocked", "reason": str(exc)})
+    return {"schema_version": SCHEMA_VERSION, "requests": requests}
+
+
+def command_mark_synced(args: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    key = _manifest_key(Path(args.source))
+    entry = state["authorized_outputs"].get(key)
+    if entry is None or entry.get("current_sha256") != args.sha256:
+        raise ArchiveError("Sync ACK does not match the current authorized output hash.")
+    entry["last_synced_sha256"] = args.sha256
+    entry["last_synced_at"] = datetime.now(UTC).isoformat()
+    _save_state(state)
+    return {"status": "synced", "stable_node_id": entry["stable_node_id"]}
+
+
+def command_ask_status(args: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    asked = args.task_id in set(state.get("asked_task_ids") or [])
+    return {"task_id": args.task_id, "should_ask": not asked, "already_asked": asked}
+
+
+def command_mark_asked(args: argparse.Namespace) -> dict[str, Any]:
+    state = _load_state()
+    asked = set(state.get("asked_task_ids") or [])
+    asked.add(args.task_id)
+    state["asked_task_ids"] = sorted(asked)[-500:]
+    _save_state(state)
+    return {"task_id": args.task_id, "already_asked": True}
+
+
+def parser() -> argparse.ArgumentParser:
+    root = argparse.ArgumentParser(description="Prepare authorized Memova Agent archives.")
+    sub = root.add_subparsers(dest="command", required=True)
+    configure = sub.add_parser("configure")
+    configure.add_argument("--vault-root", required=True)
+    configure.add_argument(
+        "--mode",
+        choices=("explicit_only", "ask_each_time", "always_auto_save"),
+        default="explicit_only",
+    )
+    configure.set_defaults(handler=command_configure)
+    prepare = sub.add_parser("prepare")
+    prepare.add_argument("--source", required=True)
+    prepare.add_argument("--task-id", required=True)
+    prepare.add_argument("--source-reference", required=True)
+    prepare.add_argument("--title")
+    prepare.add_argument(
+        "--source-kind", choices=("agent_file", "codex_task_markdown"), default="agent_file"
+    )
+    prepare.add_argument(
+        "--mode", choices=("explicit_only", "ask_each_time", "always_auto_save")
+    )
+    prepare.add_argument("--authorize", action="store_true")
+    prepare.add_argument("--scheduled", action="store_true")
+    prepare.set_defaults(handler=command_prepare)
+    scan = sub.add_parser("scan-authorized")
+    scan.set_defaults(handler=command_scan)
+    synced = sub.add_parser("mark-synced")
+    synced.add_argument("--source", required=True)
+    synced.add_argument("--sha256", required=True)
+    synced.set_defaults(handler=command_mark_synced)
+    ask = sub.add_parser("ask-status")
+    ask.add_argument("--task-id", required=True)
+    ask.set_defaults(handler=command_ask_status)
+    mark = sub.add_parser("mark-asked")
+    mark.add_argument("--task-id", required=True)
+    mark.set_defaults(handler=command_mark_asked)
+    return root
+
+
+def main() -> int:
+    try:
+        args = parser().parse_args()
+        result = args.handler(args)
+        print(json.dumps(result, ensure_ascii=False, sort_keys=True))
+        return 0
+    except (ArchiveError, OSError, json.JSONDecodeError) as exc:
+        print(json.dumps({"status": "blocked", "error": str(exc)}, ensure_ascii=False))
+        return 2
+
+
+if __name__ == "__main__":
+    sys.exit(main())
Full technical diff · 49 changed fields

changed /files/.app.json/sha256

BEFORE
"333caf4b33faceae5e71a169c696a070f4ffbcf5392c83f22704ce8a8b058311"
AFTER
"af9ff37fc68dfba75882c0f49b53ceb412fbd6924d3e97fe08efee3dedaffe77"

changed /files/.app.json/size

BEFORE
127
AFTER
98

changed /files/.codex-plugin~1plugin.json/sha256

BEFORE
"b09aeecc839ac6fbdaffa93c985edcda36eae4a10cd319f4d2e306b772f83e4b"
AFTER
"4d721d3b50a321c7069b5ab068b3709adbb9fb2fcbb57df56e857d7290ec7a5a"

changed /files/.codex-plugin~1plugin.json/size

BEFORE
1223
AFTER
10908

added /files/.mcp.json

BEFORE
Field was absent
AFTER
{
  "sha256": "be8708abebf3e796509ad32a83d2a62c427ace502f3d662daac054eece711903",
  "size": 89
}

added /files/assets~1icon.svg

BEFORE
Field was absent
AFTER
{
  "sha256": "54bd50b6408ef5c658fe724373919e3edbb220232ebd6938ab69c0517f72e7f7",
  "size": 685
}

added /files/assets~1logo.svg

BEFORE
Field was absent
AFTER
{
  "sha256": "427a49d8196f8daf05e6f948d43670f801040e3596261d7be902cdd6223897db",
  "size": 866
}

added /files/contracts~1resource_access_plugin_binding_v1.json

BEFORE
Field was absent
AFTER
{
  "sha256": "ca0e91ab63d1d80d92593d24db60e62911e9c96c1316e07391654b66f274e9be",
  "size": 3406
}

added /files/contracts~1upstream~1memova_resource_access_v1.json

BEFORE
Field was absent
AFTER
{
  "sha256": "6bef5e8c35934a2ff9d6a0dd55c7d70470ced995337f28f6c3b083ed28a4c78d",
  "size": 9185
}

added /files/menu_catalog.json

BEFORE
Field was absent
AFTER
{
  "sha256": "894363bbecb738df6aa6cea91dac994d381067049d4d866930a065cd1c6945b3",
  "size": 2509
}

added /files/scripts~1agent_archive.py

BEFORE
Field was absent
AFTER
{
  "sha256": "7ef5fe9d8292847c59543395104ec80709aedd56a992718ecefec793dd1f67c9",
  "size": 15116
}

added /files/scripts~1check_menu_catalog.py

BEFORE
Field was absent
AFTER
{
  "sha256": "d89afb741c7f73a2ac3857f3379268f00c61eec05ae2e8700738e440477bbe2f",
  "size": 638
}

added /files/scripts~1ensure_mcp_login.py

BEFORE
Field was absent
AFTER
{
  "sha256": "dd2ce35ecaa4ce7ec8f249ab962660f134515f9adcb5d714dd5e33222039bf92",
  "size": 20246
}

added /files/scripts~1kb_setup_reminder.py

BEFORE
Field was absent
AFTER
{
  "sha256": "cdb69e55bcf1faa65fa6664a4bd6a91abf7f9ab11db0ff7be5245c4c2a713fe5",
  "size": 5470
}

added /files/scripts~1mcp_connection_auth.py

BEFORE
Field was absent
AFTER
{
  "sha256": "3df8962e9d5c66a5298d9a9e6cbdc4d17755cc9d73d2f139bc3ee26256ed9bc2",
  "size": 21361
}

added /files/scripts~1mcp_credential_store.py

BEFORE
Field was absent
AFTER
{
  "sha256": "106077ee2270b0168ff15a7caded91da9fad252f1c1164b6e1d4228028b1712b",
  "size": 13043
}

added /files/scripts~1memova_menu.py

BEFORE
Field was absent
AFTER
{
  "sha256": "a31d626d81f92189782138cd438a7c070e4bb0104d4a47ad2024013816cf7c66",
  "size": 2503
}

added /files/scripts~1validate_resource_access_contract.py

BEFORE
Field was absent
AFTER
{
  "sha256": "130b4b179e301d7b0984822721c1c9633ff824c7e00f280f89fb98f1aebe486e",
  "size": 19271
}

added /files/scripts~1version_check.py

BEFORE
Field was absent
AFTER
{
  "sha256": "431220554511a5ffc66b14ac414259dbc50f24e97a050358fb35e1cc19b4c72e",
  "size": 10129
}

added /files/skills~1memova-agent-archive~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "f5acafcc0aded82b7173384f3be02bf2be31ab85b0842a15828c29e40c5539d1",
  "size": 6335
}

added /files/skills~1memova-agent-archive~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "080bd0c786e329c6538576681bc233bebcc0419dfa0dc34e78a7dd056bd46fec",
  "size": 463
}

added /files/skills~1memova-connect~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "8254a65d2ebe8a9e518fc0be28b0494a3b002e61d2b540812579fdf2b04ac19b",
  "size": 3181
}

added /files/skills~1memova-connect~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "7265de61625ee0b57733e64ab4807ac422a15bfd96a35b609f012c666cba3d71",
  "size": 248
}

added /files/skills~1memova-explicit-import~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "a9846d3d749b53a822c2b955cb75974dee16bfea84c33be3e2aba4170b6a318e",
  "size": 7700
}

added /files/skills~1memova-explicit-import~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "eb925da8a56261a8efb3869710fdba83fd4641da830acb3544c2c17145c4c115",
  "size": 483
}

added /files/skills~1memova-explicit-import~1scripts~1preview_selected_import.py

BEFORE
Field was absent
AFTER
{
  "sha256": "f4f01224c0b245dcb7ec5021714162293c758b8a1b7ec7d468ac1b197d9d06fb",
  "size": 7909
}

added /files/skills~1memova-knowledge~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "08da7d9d3589124da1d35524587ef2080c2455d191bb86ee4ed528695bcdf083",
  "size": 5445
}

added /files/skills~1memova-knowledge~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "5b2b81d6559f0d588fb352b303082607953d0cac2b2bc093210862253c68998a",
  "size": 496
}

added /files/skills~1memova-menu~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "88e9ce6c3a261ae5e6f633228e6f7188d2c7884abf15efc8941f417d1d23fc5e",
  "size": 8933
}

added /files/skills~1memova-menu~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "a3543b03bd48af221f0f0354f37fc32d5062bbf38c34993d8dad4cf3be05b1ee",
  "size": 204
}

added /files/skills~1memova-personal-manual~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "5e2ee8b0ae48ac8a469dc61de899e515e0356f48115cd7fa6371cb7a6d2f9b7d",
  "size": 11321
}

added /files/skills~1memova-personal-manual~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "409d332354b3bfbbd1a30e2262ad44cb393774360e067d359c196ccd4dbf7d9a",
  "size": 536
}

added /files/skills~1memova-personal-manual~1references~1local-artifacts.md

BEFORE
Field was absent
AFTER
{
  "sha256": "b7aa91d7a130338792a57cbe2937aea23fe6c94f7389dee3c7bd01035854dfa6",
  "size": 1914
}

added /files/skills~1memova-personal-manual~1scripts~1prepare_personal_manual.py

BEFORE
Field was absent
AFTER
{
  "sha256": "51cd409550a765c45b0fa3e78c9eb7309d308c769ac5aa83443f46616644bcc8",
  "size": 19703
}

added /files/skills~1memova-resource-access~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "360b19832d8891f20b05a0ec0d6eca849b4afb80915909edc7596fc335b932b3",
  "size": 13511
}

added /files/skills~1memova-resource-access~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "8f089f456a2cf60ce08dd3f006f8c835255c1b6b7f2f07af54aedc7c75c42d08",
  "size": 580
}

added /files/skills~1memova-vault-diagnose~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "b4c38e582baeb21e69ec8b04d5efa690739989a38c82468d1d3ad19465203a34",
  "size": 4809
}

added /files/skills~1memova-vault-diagnose~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "cc32fa628fb4f5c3c91f750dcf72bfdf4704fda2efb33dd1281f11b5ecaf49b6",
  "size": 469
}

added /files/skills~1memova-vault-setup~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "3c4410dac28396080939f749581e42a7ce67fa704975f7d4b19aa8eee31d4537",
  "size": 12497
}

added /files/skills~1memova-vault-setup~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "0c1cbe0d82408b2b2c885f90b70d0a85bcb34ec0ac20a17386c5220af5189841",
  "size": 475
}

added /files/skills~1memova-vault-setup~1scripts~1create_memova_vault.py

BEFORE
Field was absent
AFTER
{
  "sha256": "3272b0f7f648e402f5035e5f10b75ca18fd143c86031fa470bd162a17e054c22",
  "size": 4151
}

added /files/skills~1memova-vault-setup~1scripts~1diagnose_memova_vault.py

BEFORE
Field was absent
AFTER
{
  "sha256": "b4d6501f56f865473cda4aa7ca188735338011f7c962795bd0b4145a1e8e95a8",
  "size": 8060
}

added /files/skills~1memova-vault-setup~1scripts~1find_vault_locations.py

BEFORE
Field was absent
AFTER
{
  "sha256": "850c56ae9b5aa729964d2eb7e22a0ff7d37fd8d2fe89e0e6bc6d469caa6c5bd6",
  "size": 1965
}

added /files/skills~1memova-vault-setup~1scripts~1inspect_vault.py

BEFORE
Field was absent
AFTER
{
  "sha256": "7515a4d226c3a8acecfc662fb573e64a136f60aedb2460f6ed8afef212abee18",
  "size": 748
}

added /files/skills~1memova-vault-setup~1scripts~1memova_vault_lib.py

BEFORE
Field was absent
AFTER
{
  "sha256": "0d7977b3485222bbebf7cf6520c01b0c55712679a7939c30689b729bcbe23bef",
  "size": 97146
}

added /files/skills~1memova-vault-setup~1scripts~1setup_fixture_harness.py

BEFORE
Field was absent
AFTER
{
  "sha256": "605d8d19a51b551611bca2cdd612651e27a490a66d9f9b5958d39d876e27e3a6",
  "size": 50807
}

added /files/skills~1memova-vault-setup~1scripts~1validate_memova_vault.py

BEFORE
Field was absent
AFTER
{
  "sha256": "0c0632e1a8e192fae3b9802501cc298a2c3887ce63a552a469e32b83d6737269",
  "size": 2681
}

added /files/skills~1memova-workflow~1SKILL.md

BEFORE
Field was absent
AFTER
{
  "sha256": "7b98b4534cdec921a6b82f422f445a46d3a4f78cbb4feeabdfee1b3b924cb264",
  "size": 10156
}

added /files/skills~1memova-workflow~1agents~1openai.yaml

BEFORE
Field was absent
AFTER
{
  "sha256": "ade51e2a4a35f1ce6b1d05bda9d183ce58a10aedeab183bedc6382fbe5b47bbd",
  "size": 445
}
Full snapshot data
{
  "files": {
    ".app.json": {
      "sha256": "af9ff37fc68dfba75882c0f49b53ceb412fbd6924d3e97fe08efee3dedaffe77",
      "size": 98
    },
    ".codex-plugin/plugin.json": {
      "sha256": "4d721d3b50a321c7069b5ab068b3709adbb9fb2fcbb57df56e857d7290ec7a5a",
      "size": 10908
    },
    ".mcp.json": {
      "sha256": "be8708abebf3e796509ad32a83d2a62c427ace502f3d662daac054eece711903",
      "size": 89
    },
    "assets/icon.svg": {
      "sha256": "54bd50b6408ef5c658fe724373919e3edbb220232ebd6938ab69c0517f72e7f7",
      "size": 685
    },
    "assets/logo.svg": {
      "sha256": "427a49d8196f8daf05e6f948d43670f801040e3596261d7be902cdd6223897db",
      "size": 866
    },
    "contracts/resource_access_plugin_binding_v1.json": {
      "sha256": "ca0e91ab63d1d80d92593d24db60e62911e9c96c1316e07391654b66f274e9be",
      "size": 3406
    },
    "contracts/upstream/memova_resource_access_v1.json": {
      "sha256": "6bef5e8c35934a2ff9d6a0dd55c7d70470ced995337f28f6c3b083ed28a4c78d",
      "size": 9185
    },
    "menu_catalog.json": {
      "sha256": "894363bbecb738df6aa6cea91dac994d381067049d4d866930a065cd1c6945b3",
      "size": 2509
    },
    "scripts/agent_archive.py": {
      "sha256": "7ef5fe9d8292847c59543395104ec80709aedd56a992718ecefec793dd1f67c9",
      "size": 15116
    },
    "scripts/check_menu_catalog.py": {
      "sha256": "d89afb741c7f73a2ac3857f3379268f00c61eec05ae2e8700738e440477bbe2f",
      "size": 638
    },
    "scripts/ensure_mcp_login.py": {
      "sha256": "dd2ce35ecaa4ce7ec8f249ab962660f134515f9adcb5d714dd5e33222039bf92",
      "size": 20246
    },
    "scripts/kb_setup_reminder.py": {
      "sha256": "cdb69e55bcf1faa65fa6664a4bd6a91abf7f9ab11db0ff7be5245c4c2a713fe5",
      "size": 5470
    },
    "scripts/mcp_connection_auth.py": {
      "sha256": "3df8962e9d5c66a5298d9a9e6cbdc4d17755cc9d73d2f139bc3ee26256ed9bc2",
      "size": 21361
    },
    "scripts/mcp_credential_store.py": {
      "sha256": "106077ee2270b0168ff15a7caded91da9fad252f1c1164b6e1d4228028b1712b",
      "size": 13043
    },
    "scripts/memova_menu.py": {
      "sha256": "a31d626d81f92189782138cd438a7c070e4bb0104d4a47ad2024013816cf7c66",
      "size": 2503
    },
    "scripts/validate_resource_access_contract.py": {
      "sha256": "130b4b179e301d7b0984822721c1c9633ff824c7e00f280f89fb98f1aebe486e",
      "size": 19271
    },
    "scripts/version_check.py": {
      "sha256": "431220554511a5ffc66b14ac414259dbc50f24e97a050358fb35e1cc19b4c72e",
      "size": 10129
    },
    "skills/memova-agent-archive/SKILL.md": {
      "sha256": "f5acafcc0aded82b7173384f3be02bf2be31ab85b0842a15828c29e40c5539d1",
      "size": 6335
    },
    "skills/memova-agent-archive/agents/openai.yaml": {
      "sha256": "080bd0c786e329c6538576681bc233bebcc0419dfa0dc34e78a7dd056bd46fec",
      "size": 463
    },
    "skills/memova-connect/SKILL.md": {
      "sha256": "8254a65d2ebe8a9e518fc0be28b0494a3b002e61d2b540812579fdf2b04ac19b",
      "size": 3181
    },
    "skills/memova-connect/agents/openai.yaml": {
      "sha256": "7265de61625ee0b57733e64ab4807ac422a15bfd96a35b609f012c666cba3d71",
      "size": 248
    },
    "skills/memova-explicit-import/SKILL.md": {
      "sha256": "a9846d3d749b53a822c2b955cb75974dee16bfea84c33be3e2aba4170b6a318e",
      "size": 7700
    },
    "skills/memova-explicit-import/agents/openai.yaml": {
      "sha256": "eb925da8a56261a8efb3869710fdba83fd4641da830acb3544c2c17145c4c115",
      "size": 483
    },
    "skills/memova-explicit-import/scripts/preview_selected_import.py": {
      "sha256": "f4f01224c0b245dcb7ec5021714162293c758b8a1b7ec7d468ac1b197d9d06fb",
      "size": 7909
    },
    "skills/memova-knowledge/SKILL.md": {
      "sha256": "08da7d9d3589124da1d35524587ef2080c2455d191bb86ee4ed528695bcdf083",
      "size": 5445
    },
    "skills/memova-knowledge/agents/openai.yaml": {
      "sha256": "5b2b81d6559f0d588fb352b303082607953d0cac2b2bc093210862253c68998a",
      "size": 496
    },
    "skills/memova-menu/SKILL.md": {
      "sha256": "88e9ce6c3a261ae5e6f633228e6f7188d2c7884abf15efc8941f417d1d23fc5e",
      "size": 8933
    },
    "skills/memova-menu/agents/openai.yaml": {
      "sha256": "a3543b03bd48af221f0f0354f37fc32d5062bbf38c34993d8dad4cf3be05b1ee",
      "size": 204
    },
    "skills/memova-personal-manual/SKILL.md": {
      "sha256": "5e2ee8b0ae48ac8a469dc61de899e515e0356f48115cd7fa6371cb7a6d2f9b7d",
      "size": 11321
    },
    "skills/memova-personal-manual/agents/openai.yaml": {
      "sha256": "409d332354b3bfbbd1a30e2262ad44cb393774360e067d359c196ccd4dbf7d9a",
      "size": 536
    },
    "skills/memova-personal-manual/references/local-artifacts.md": {
      "sha256": "b7aa91d7a130338792a57cbe2937aea23fe6c94f7389dee3c7bd01035854dfa6",
      "size": 1914
    },
    "skills/memova-personal-manual/scripts/prepare_personal_manual.py": {
      "sha256": "51cd409550a765c45b0fa3e78c9eb7309d308c769ac5aa83443f46616644bcc8",
      "size": 19703
    },
    "skills/memova-resource-access/SKILL.md": {
      "sha256": "360b19832d8891f20b05a0ec0d6eca849b4afb80915909edc7596fc335b932b3",
      "size": 13511
    },
    "skills/memova-resource-access/agents/openai.yaml": {
      "sha256": "8f089f456a2cf60ce08dd3f006f8c835255c1b6b7f2f07af54aedc7c75c42d08",
      "size": 580
    },
    "skills/memova-vault-diagnose/SKILL.md": {
      "sha256": "b4c38e582baeb21e69ec8b04d5efa690739989a38c82468d1d3ad19465203a34",
      "size": 4809
    },
    "skills/memova-vault-diagnose/agents/openai.yaml": {
      "sha256": "cc32fa628fb4f5c3c91f750dcf72bfdf4704fda2efb33dd1281f11b5ecaf49b6",
      "size": 469
    },
    "skills/memova-vault-setup/SKILL.md": {
      "sha256": "3c4410dac28396080939f749581e42a7ce67fa704975f7d4b19aa8eee31d4537",
      "size": 12497
    },
    "skills/memova-vault-setup/agents/openai.yaml": {
      "sha256": "0c1cbe0d82408b2b2c885f90b70d0a85bcb34ec0ac20a17386c5220af5189841",
      "size": 475
    },
    "skills/memova-vault-setup/scripts/create_memova_vault.py": {
      "sha256": "3272b0f7f648e402f5035e5f10b75ca18fd143c86031fa470bd162a17e054c22",
      "size": 4151
    },
    "skills/memova-vault-setup/scripts/diagnose_memova_vault.py": {
      "sha256": "b4d6501f56f865473cda4aa7ca188735338011f7c962795bd0b4145a1e8e95a8",
      "size": 8060
    },
    "skills/memova-vault-setup/scripts/find_vault_locations.py": {
      "sha256": "850c56ae9b5aa729964d2eb7e22a0ff7d37fd8d2fe89e0e6bc6d469caa6c5bd6",
      "size": 1965
    },
    "skills/memova-vault-setup/scripts/inspect_vault.py": {
      "sha256": "7515a4d226c3a8acecfc662fb573e64a136f60aedb2460f6ed8afef212abee18",
      "size": 748
    },
    "skills/memova-vault-setup/scripts/memova_vault_lib.py": {
      "sha256": "0d7977b3485222bbebf7cf6520c01b0c55712679a7939c30689b729bcbe23bef",
      "size": 97146
    },
    "skills/memova-vault-setup/scripts/setup_fixture_harness.py": {
      "sha256": "605d8d19a51b551611bca2cdd612651e27a490a66d9f9b5958d39d876e27e3a6",
      "size": 50807
    },
    "skills/memova-vault-setup/scripts/validate_memova_vault.py": {
      "sha256": "0c0632e1a8e192fae3b9802501cc298a2c3887ce63a552a469e32b83d6737269",
      "size": 2681
    },
    "skills/memova-workflow/SKILL.md": {
      "sha256": "7b98b4534cdec921a6b82f422f445a46d3a4f78cbb4feeabdfee1b3b924cb264",
      "size": 10156
    },
    "skills/memova-workflow/agents/openai.yaml": {
      "sha256": "ade51e2a4a35f1ce6b1d05bda9d183ce58a10aedeab183bedc6382fbe5b47bbd",
      "size": 445
    }
  }
}

SHA-256 of public snapshot: c9fc0f7767b2429980a672046ee55277b419ec8f437b75a2051fe27afb04c9d8