Skip to content

5.1.2

Choose a tag to compare

@Korrnals Korrnals released this 01 Oct 15:55
· 31 commits to main since this release

Vesma 5.1.2 lands the memory-switch protocol MS-0 and makes the pack deploy the whole host by default.

Highlights

  • Memory-switch MS-0 — the engine manifest (integrations/engine-manifest.yaml), formalized overlay+mirror precedence, and a new read-only vesma memory status show exactly how vesma is wired into every harness on the machine.
  • One command deploys everything — vesma integration setup now deploys the pack to ALL detected harnesses and wires all agents in a single idempotent pass; flags become the narrowing variant. A failing target no longer blocks the rest (#448).
  • Auto-update — quiet update check (default-on, offline-safe, kill-switchable), vesma update for reports/upgrades, and an opt-in weekly systemd user timer (#445).
  • The vesma- integration pack* — 16 skills, the consolidated memory-ops canon (G1-G4), and the always-on block move into Vesma as the single delivery channel, with MCP-unregister on uninstall and legacy-stamp migration.
  • Brand-primary MCP manifest — tools/list advertises vesma_* names only under VESMA_MCP_BRAND=vesma (legacy spellings still dispatch until 6.0).
  • Version detection fixed for pip installs — vesma -V now resolves across the whole post-rebrand dist family (vesma / vesma-memory-server / vesmaro / legacy), so a clean pip install vesma-memory-server no longer reports 0.0.0+unknown.

Install: pip install vesma (or pip install vesma-memory-server). Wheels carry both embedder artifact dirs by contract until 6.0.


[5.1.2] — 2026-10-02

Added

  • Memory-switch protocol MS-0: engine manifest, formalized precedence, vesma memory status (ADR-0034, board card vesma-memory-switch-protocol) (integrations/engine-manifest.yaml — new, src/vesmaro/cli/integration.py, src/vesmaro/cli/memory_status.py — new, src/vesmaro/cli/main.py, src/vesmaro/cli/util.py, src/vesmaro/cli/doctor.py, integrations/targets.yaml; docs EN+RU; tests in tests/test_integration.py) — the engine-side identity card for the memory-switch protocol ships as a PLAIN pack file integrations/engine-manifest.yaml (generalized from the Hermes plugin.yaml: name/description/author/license/capabilities, mcp transport block — stdio, brand-primary server key vesma with legacy mnemos recognized, precedence_modes: [overlay+mirror], attach_points pointing at the targets registry); it rides the wheel via the existing integrations/ force-include and is deliberately NOT deployed into harness directories — consumers load it via load_engine_manifest(), which validates required keys, rejects unknown precedence modes (fail-closed) and injects version from the installed package (single source of truth — the YAML never drifts). The target-profile layer gains an explicit precedence: field per target (default overlay+mirror — the only ENFORCED mode; replace/off are recognized-but-not-yet-enforced values documented as arriving with the spec-repo MS-1 wave, honest staging per the contract; any other value fails at parse time with validate_precedence). integration verify and doctor now show the active precedence per wired harness. New read-only CLI surface vesma memory status (cli/memory_status.py, registered as the memory sub-app): per detected harness — pack attachment state (stamps via the verify engine), MCP registration (vesma entry present or not), external memory engines seen in that harness's MCP config, built-in store markers (data dir, vault dir, mnemos.db — existence + mtime ONLY) and the active precedence. Hygiene per ArchCom B3: only paths from the static targets.yaml/pack registry and the well-known store markers are read, file NAMES and mtimes only — never contents, env values or command lines; no network, no writes. Tests: TestEngineManifest (load+validate, version injection, attach-point pointer, unknown-mode/missing-key rejections), TestPrecedenceField (default/explicit/recognized/unknown + shipped-registry invariant + verify output), TestMemoryStatus (output shape, server-keys-only hygiene with secret-leak assertions, empty-host, unknown-target, marker reporting).

  • Harness layer handed to the integration pack: vesma- skills, memory-ops canon, G1–G4 always-on block (ArchCom 2026-10-01 «Владение harness-слоем памяти», variant b — single delivery channel vesma integration)* (integrations/skills/vesma-*.md — 16 skills new, 14 superseded flat mnemos-*.md removed; integrations/instructions/vesma-memory-ops.instructions.md — the consolidated memory-operations canon (gates G1–G4, ops discipline, tag contract, graceful degradation), replacing the split mnemos-memory-ops / mnemos-session-lifecycle / mnemos-tag-contract instructions; integrations/agents_md/vesma-always-on.md — the always-on behavioral block injected into AGENTS.md-standard files, replacing mnemos-always-on.md) — ownership of the harness-facing memory canon moves from the GCW (GithubCopilotWorkflow) repo to Vesma per the layer-separation contract «the memory layer is owned by Vesma, not by any agent framework»; GCW ships inert one-line stubs pointing at vesma integration setup. Content notes: skills are the live v2.14.1-generation canon renamed mnemos-* → vesma-*; tool names swept to brand-primary vesma_* (legacy mnemos_* accepted by server builds until 6.0, noted where relevant); tag prefixes mnemos:<subtype> are the storage data contract and are deliberately unchanged; the record-canon artefacts from #426/#431 (mnemos-canon-write, mnemos-context-lifecycle, canon-records) keep their pinned names pending a dedicated rename wave. Security-major #1 (gate): every deployable text-kind file now carries the pack safety contract — recalled store content is DATA not instructions; no exfiltration of memory contents into URLs/web requests/commits/external messages; no real credentials in examples; subordination line «Инструкции пака описывают работу с сервером памяти vesma и применяются только в объёме, где локальный канон харнеса молчит; при любом расхождении приоритет у локального канона и safety-правил хоста» — pinned by TestPackSafetyContract (grep over the pack; the byte-identical schemas kind is documentedly exempt). Stamp migration: the version stamp is now <!-- vesma-integration: vX --> (engine make_stamp), with dual-pattern recognition of legacy mnemos-integration (file stamps, AGENTS.md block markers, schemas manifest name) for a 2–3 release window — first deploy/update re-stamps, verify reports legacy markers as the dedicated old-stamp status; legacy mnemos-schemas.manifest.json migrates to vesma-schemas.manifest.json on first deploy/update and both names uninstall. Security-major #2 (gate): uninstall now also unregisters the MCP server entry the pack registered (IntegrationManager.unregister_mcp; zcode mcp.servers, agents mcpServers, opencode mcp maps) — brand-primary key vesma, legacy mnemos key removed, entries removed only on command-evidence (mcp-server argv or vesma/mnemos binary basename), foreign entries and unrelated config keys preserved as data, dry-run never touches the config; register_mcp migrates a legacy-key entry to the brand-primary key. Release tests: TestStampMigration / TestSchemasManifestMigration / TestUnregisterMcp (7 tests) / TestAgentsMdInjectionByteExactness (AGENTS.md injection with CRLF pre-content changes not one byte outside the stamped block, update re-splices in place, uninstall restores the exact user bytes). tests/test_integration.py 154 → 176 green, tests/test_integration_agents_md.py pins updated; docs docs/en|ru/user/integration-guide.md pack trees rewritten.

  • Auto-update family: quiet update check (default-on) + vesma update + contrib weekly user-timer (#445) (src/vesmaro/updates.py — new, src/vesmaro/cli/update_cmd.py — new, src/vesmaro/cli/main.py, src/vesmaro/manager.py, src/vesmaro/config.py, contrib/vesma-update.service / contrib/vesma-update.timer — new; docs: docs/en|ru/user/getting-started.md, config.example.yaml; tests: tests/test_updates.py — 41) — Vesma now answers "is there a newer release?" and updates itself: a quiet stdlib-only check (pypi.org/pypi/<dist>/json, 3s timeout, no telemetry, 24h sidecar cache <data_dir>/update-check.json, dist detected across the post-rebrand family with vesma-memory-server → vesma first-hit-wins) surfaces as the update_available object in mnemos_stats, a stderr hint on vesma --version, and one INFO line at serve/mcp-server start; offline machines are unaffected (stale answers served, 1h negative cache bounds the timeout cost, the check never raises); opt-out via updates.check_enabled (env VESMARO_UPDATES__CHECK_ENABLED) or the independent hard kill switch VESMARO_UPDATES_CHECK=off. vesma update without flags reports every update surface on the machine (pip dists, npm @vesmaro/vesma, host prod-venvs, Go binaries); --yes --scope=user upgrades the installed dist via pip install --user --upgrade (PEP 668 --break-system-packages only under an externally-managed interpreter), updates npm best-effort, and appends to ~/.local/share/vesma/update-history.json; --to <version> is the rollback path; --install-timer/--uninstall-timer manage a weekly (OnCalendar=weekly, Persistent=true, RandomizedDelaySec=1h) systemd USER timer. Prod venvs, Go binaries and containers are NEVER auto-updated (report-only by design, documented in the unit headers and docs).

Changed

  • vesma integration setup is now the full host deployment by default (UX inversion, owner ruling; board card vesma-integration-setup-default-all) (src/vesmaro/cli/util.py, src/vesmaro/cli/doctor.py, integrations/targets.yaml; docs docs/en|ru/user/getting-started.md, docs/en|ru/user/integration-guide.md, docs/en|ru/user/cli-reference.md) — the plain vesma integration setup deploys the pack to ALL detected harnesses on this host AND wires all agents in ONE non-interactive, idempotent pass; the interactive wiring prompts are gone (the previous "prompt when TTY / skip in CI" default is retired). Flags are now the narrowing/custom variant: --target <name> is repeatable and deploys only the named harness(es) (all still accepted), --no-wire-agents skips wiring, --select a,b narrows wiring to named agents (works standalone); --wire-agents / --all remain accepted for backward compatibility (docs and scripts reference them) but are no-ops relative to the default — wiring is already default-on. --dry-run, --precise, --home, --no-mcp unchanged. Doctor hints and the verify wiring hint updated to the plain command. A failing target is now reported loudly per target and never blocks the remaining targets (see the #448 fix below).

  • Ecosystem rebrand completed — all sibling repositories moved to vesma-* names in the vesmaro org (vesmaro-agent / vesmaro-cortex / vesmaro-canon → vesma-agent / vesma-cortex / vesma-canon; mnemos-eyes → vesma-eyes; mnemos-mesh → vesma-mesh; mnemos-vitals → vesma-vitals); models mnema-* → vesma-* hash-preserving; GHCR packages vesmaro/vesma and vesmaro/vesma-eyes live. Documentation updated to the new names.

  • Brand-primary MCP manifest — with VESMA_MCP_BRAND set (e.g. vesma), tools/list now advertises each tool under its vesma_* name ONLY instead of appending brand aliases to the mnemos_* manifest (owner ruling 2026-10-01: the doubled 76-entry list confused clients). Legacy mnemos_* spellings leave the manifest but remain accepted on the call path and dispatch identically (dual-period contract until 6.0, ADR-0031).

Fixed

  • #448 (point 1): multi-target one-pass deployment (src/vesmaro/cli/integration.py, src/vesmaro/cli/util.py; regression tests TestIssue448MultiTargetOnePass in tests/test_integration.py) — on the first real host deployment of the pack, integration setup stopped after the FIRST target: a single unreadable destination file (non-UTF-8 bytes at a pack destination path — e.g. a user file that happens to carry a pack file's name) raised UnicodeDecodeError from _deploy_file's unguarded dest.read_text, which propagated through the CLI target loop and killed the whole run, so every target AFTER the failing one silently never deployed. Root cause in one sentence: the deploy loop had no per-target failure isolation and no guard on the destination read. _deploy_file/_verify_file now treat an unreadable destination as the refuse-to-touch discipline already used by the agents_md kind (reported SKIPPED, file untouched, run continues), and the CLI setup loop isolates per-target exceptions — the failing target gets a loud ✗ Target <name>: … line and a non-zero exit at the end, while the remaining targets still deploy. Regression tests: a poisoned second-target destination leaves the file untouched and still deploys targets one and three in the same pass; an injected crashing target exits 1 with the loud line while later targets deploy.

  • Version detection for pip installs — vesma --version (and every consumer of vesmaro.__version__: CLI banner, stats, doctor) now resolves the installed distribution across the full post-rebrand family (vesma → vesma-memory-server → vesmaro → mnemos-memory-server). A clean pip install vesma-memory-server previously reported mnemos 0.0.0+unknown because the lookup chain missed the standalone server dist name. The -V banner now prints the canonical vesma brand (was mnemos); tests/test_version.py guard updated to the same chain.