v4.1.0 — Vault-backed harness state + folder rename
MINOR. ROADMAP-V4 item #26. The first BUILD on top of the V4.0.0 reorganization. Per-project harness state — PLAN.md, progress.md, the four ROADMAP*.md files (slim + V4 + V5 + V6), FOLLOWUPS.md, features.json, init.sh, known-migrations.md, verify.{sh,ps1}, .promoted-progress-cursor, archived plans (PLAN.archive.YYYYMMDD-*.md), designs/ subtree, and the deprecated project.json — all relocate from <project>/.harness/ to <vault>/projects/<slug>/_harness/. The vault top-level folder personal-projects/ renames to projects/ in the same release. Backward-compat preserved as a release gate: legacy <project>/.harness/<file> reads still work via the resolver chain's tier-2 fallback with a one-warn-per-session-per-file deprecation notice; writes go only to vault unless <vault>/projects/<slug>/_harness/.project-mode reads local (the operator-opt-out escape hatch for reversibility). The reorg is additive — no breaking changes for v4.0.0 operators. Crickets unaffected (stays at v2.0.0). Single-repo release. See HLD V4.3 subsections for the architectural arc.
Added
-
scripts/harness_memory.py— new resolver chain + dispatcher primitives:_vault_projects_dir(vault)— dual-path helper preferring<vault>/projects/, falling back to<vault>/personal-projects/during the transition window.resolve_project(context)→{slug, vault_path, project_root, layout}wherelayout ∈ {"new", "legacy", "none"}lets downstream callers decide warn-once behavior.vault_state_path(resolution, filename)— pure path-construction; returns<vault>/projects/<slug>/_harness/<file>from a resolution dict.read_state_file(resolution, filename)— tries vault first; falls back to legacy<project>/.harness/<file>with a one-warn-per-session-per-file deprecation notice; honors.project-mode=localopt-out per locked DC-3.write_state_file(resolution, filename, content)— atomic tmp+rename to vault path; raisesValueErrorif resolution lacks vault_path; honors.project-mode=localredirect to legacy.warn_once(filename, source)— module-level session-scoped set; idempotent stderr emission.safe_write_replace_style(path, new_content, *, expected_mtime=None)— atomic write with optional concurrent-modification check; raisesConcurrentModificationErrorwhen mtime drifts.detect_conflict_files(vault_root)— walks vault for GDrive(conflicted copy …)markers; returns[{conflict, base, rel}]list. Companion regex helper strips marker variants (with/without device suffix; with/without "from ") to infer the canonical base path.
-
harness/hooks/conflict-merger-session-start/— new SessionStart hook (claude-code-only, non-blocking). Detects GDrive conflict files on session boot; surfaces operator-facing notice on stderr per pair; never freezes session start. Configurable viaHARNESS_CONFLICT_MERGER_MODEenv (interactive/silent/off). -
scripts/rename-vault-personal-projects.{sh,ps1}— vault-side renamer.mv personal-projects/ projects/+ portable Python-driven in-place sed sweep across_always-load/entries,_idea-incubator/entries (wikilinks + forward-looking promotion destinations),personal-private/**/*.md, and project-tree_index.mdfrontmattergroup:fields + wikilinks._meta/deliberately excluded (historical narrative preserved).--previewmode; idempotent; post-run integrity check. -
scripts/migrate-harness-to-vault.{sh,ps1}— per-project state migration. Resolves slug viavault_project.py; layout-aware; per-file conflict detection (byte-identical → skip; different content → WARN + don't overwrite + advise operator-merge); writes.migrated-from-pre-v4.1marker with full provenance; sets.project-mode=vault;--preview/--cleanup/--rollback/--yesflags. Cleanup preserves.evidence-readsper DC-1 (runtime ephemeral). -
scripts/list-plans.{sh,ps1}— cross-repo convenience surface. Walks<vault>/projects/*/_harness/PLAN.md; parses title + Status + mtime; renders one-row-per-project table. Default shows planning + in-progress;--allincludes done + complete. The "show me all in-flight plans" UX item from the V4 #26 design conversation. -
23 new unit tests in
scripts/test_harness_memory.pyacross 5 test classes (TestVaultProjectsDir × 4, TestResolveProject × 5, TestVaultStatePath × 4, TestReadStateFile × 6, TestWriteStateFile × 4, TestSafeWriteReplaceStyle × 7, TestDetectConflictFiles × 8). Total: 71 tests in 0.24s.
Changed
-
All 5 phase specs +
pipelines/bugfix.mdgain a> [!NOTE]callout near the top declaring the resolver chain. Phase specs describe WHAT to read/write (logical file shortnames likePLAN.md); the dispatcher decides WHERE. Inline.harness/<file>path references survive as factual filename markers. 04-review's callout notes read-only semantics; 05-release's notes that CHANGELOG.md stays per-repo (publicly shipped, not state). -
Folder-rename sweep propagated through harness scripts + memory skill body + memory scripts + sub-agent specs + operator-facing docs. Residual
personal-projects/references survive only as: (1) the_VAULT_PROJECTS_REL_LEGACYconstant + dual-path resolver code; (2) backward-compat / pre-rename / legacy-alias narrative annotations; (3) the test fixture for the legacy resolver path. Historical CHANGELOG + PLAN.archive entries deliberately preserved.
Internal
harness/scripts/install-plugin.shpath references updated post-V4-#36 —SRC_PLUGINSnow resolves to$HARNESS_ROOT/harness/plugins.- Pre-v3.1.0-rename leftover discovered during dogfood:
agentm/.harness/project.jsoncarriedgithub.repo: alexherrero/agentic-harnessfrom the agentic-harness → agentm rename. Corrected toalexherrero/agentm+ added explicitvault_project: agentmto avoid tier-2 ambiguity. Logged as a known-issue for operators upgrading from very-old installs: anyproject.jsonwith agithub.repofield that doesn't match the current GitHub repo name should be updated before runningmigrate-harness-to-vault.sh.
Migration
For v4.0.0 → v4.1.0 operators with <project>/.harness/<files>:
# One-time vault rename (run from anywhere; uses MEMORY_VAULT_PATH env):
bash ~/Antigravity/agentm/scripts/rename-vault-personal-projects.sh --preview # review
bash ~/Antigravity/agentm/scripts/rename-vault-personal-projects.sh # live
# Per-project state migration:
bash ~/Antigravity/agentm/scripts/migrate-harness-to-vault.sh ~/path/to/repo
# Verify:
ls "$MEMORY_VAULT_PATH/projects/<slug>/_harness/"
# Optional cleanup once verified:
bash ~/Antigravity/agentm/scripts/migrate-harness-to-vault.sh --cleanup ~/path/to/repo
# Rollback at any time:
bash ~/Antigravity/agentm/scripts/migrate-harness-to-vault.sh --rollback ~/path/to/repoOperators who pulled v4.0.0 but haven't run any migration command continue working unchanged — the resolver chain falls back to legacy <project>/.harness/<file> paths with a one-warn-per-session-per-file deprecation notice.
Cross-references
- HLD updates:
- agent-memory-evolution.md § V4 release milestones — V4.3 subsection.
- device-wide-architecture.md § Update history — v0.3 entry.
- Plan:
.harness/PLAN.mdplan #20 (now vault-backed at<vault>/projects/agentm/_harness/PLAN.md). - Locked design calls in plan #20: DC-1 (
.evidence-readsstays per-cwd); DC-2 (warn-once-per-session-per-file); DC-3 (.project-modelives vault-side at<vault>/projects/<slug>/_harness/.project-mode); DC-4 (marker file.migrated-from-pre-v4.1matches semver boundary). - Dogfood findings (plan #20 task 9): 3 bugs caught + fixed mid-session (preview-sweep gap;
_idea-incubator/wikilinks; stalegithub.repoin agentm's project.json). 6 watchlist items deferred to operator's real-use sessions post-release.
Deferred to subsequent v4.x releases
- Hard-cut deprecation of legacy
<project>/.harness/paths — ships at the eventual deprecation release (likely v4.2.0 or v4.3.0) once migration is fully dogfooded across operator's vault for ~weeks of real use. - V4 #37 (vec-index drift detection) — next plan after #26 closes; benefits from operating against migrated state.
- V4 #30 (global-install harness +
--scope userdefault + auto-stay-in-sync) — follows #37. - Mobile-readable summary head on
progress.md— deferred until real-use measurement confirms it's needed. - Recall-exclusion patterns for
<vault>/projects/<slug>/_harness/**— deferred until real/memory searchagainst post-migration vault surfaces measurable noise.