Imported from Zenosyne-Technologies/agent-operating-kit (
skills/validate-kit/SKILL.md). Install upstream withnpx skills add Zenosyne-Technologies/agent-operating-kit --skill validate-kit. Copyright stays with the author.
Validate the kit
- Static gate: run
bash scripts/validate-kit.sh,bash scripts/test-migrations.sh,bash scripts/test-claude-md-split.sh(the split planner's fixtures and its inline mutation checks) andbash scripts/mutate-migrations.shfrom the repo root. Any FAIL stops here — fix before scenarios. The migration suite owns the release-migration mechanics as executable fixtures (one per known defect, plus--checkpurity, re-run no-op andgit revertconsistency); the scenarios below check the skills wrapped around them, not the mechanics. - Scenarios — each in a throwaway git-initialized scratch repo (temp dir; delete afterward). Act as the installing/upgrading agent yourself, following the skills literally with
${CLAUDE_PLUGIN_ROOT}= this repo root. Tracker steps run DRY (the Local tracker's brief is repo-local and always dispatches for real): fill the briefs and show them, do not dispatch — unless the user names a sandbox tracker project.- (a) Fresh install: seed a minimal repo (README + one manifest), run
skills/install-agent-os/SKILL.mdselecting the Local tracker (no external tool needed), attribution default. Verify:.marvin/agents/complete for the selection,.marvin/agents/stats-collection-brief.mdpresent,.docs/project-management/scaffolded (INDEX.md,issues/,milestones/,guide.md) when the local intake brief is dispatched, the.docs/estate seeded (index.md, the six folder seeds —plans/,researches/,refactor/,future/,information/,release-notes/—handbooks/index.mdand the three audience index.md files) with every sub-folder row resolving to a file that exists,.marvin/MEMORY.mdpresent,.marvin/CLAUDE.marvin.mdpresent and rendered (model names from the plugin's model profile, the issue-log path),CLAUDE.mdholds no kit rule and ends with the bare import@.marvin/CLAUDE.marvin.md(the planner reportsimport: presentandresult=nothing-to-do), placeholders all resolved in both, PROJECT-INFO frontmatter parses with every template key and real values (21 frontmatter keys incl.brief,telemetryandissue_log_path), no{{and no${CLAUDE_PLUGIN_ROOT}in installed files. Before running, stage an unrelated consumer edit (git adda README change): afterwards it is still staged and appears in no commit the install made (the Commit scope rule in the upgrade skill's Rules — a plaingit commitfails this). - (b) Legacy upgrade: fabricate a pre-0.7.0 shape (
docs/agents/with old files,found-by:*in ticket-filing, no PROJECT-INFO), runskills/upgrade-agent-os/SKILL.md. Verify: files moved to.marvin/agents/,.marvin/agents/stats-collection-brief.mdpresent, the.docs/estate seeded (root index, six folder seeds incl.release-notes/,handbooks/index.mdand the three audience index.md files),.marvin/MEMORY.mdpresent, references rewritten, frontmatter created and stamped (21 frontmatter keys incl.brief,telemetryandissue_log_path), relabel sweep OFFERED not executed, and the split gate ASKED beforeCLAUDE.mdchanged. - (c) Current-layout upgrade — the shape this release actually migrates. Fabricate a v0.20.0 install and commit it:
.docs/agents/(full cascade incl.tracker-config.md+stats-collection-brief.md),.docs/PROJECT-INFO.mdstampedkit_version: 0.20.0,.docs/marvin/MEMORY.md,.docs/handbooks/{developer,user,admin}/INDEX.md, plus.docs/project-management/INDEX.mdas a decoy, two reports in.docs/reports/(one kit snapshot, one hand-written, one of them in a sub-folder), and a CLAUDE.md citing the old paths — reports included. First, on that fixture, exercise the pre-v0.21.0 fallback in the four other readers —commands/info.mdmust report installed + upgradable and point atupgrade-agent-os, neverinstall-agent-os;skills/project-info/SKILL.mdmust validate.docs/PROJECT-INFO.mdIN PLACE and create no second file (a.marvin/PROJECT-INFO.mdappearing here is the destination collision that stalls the migration at exit 3 and then makes the upgrade a silent no-op);reportandplan-docsmust find their facts rather than declare the project uninstalled. Then also restamp a copy's PROJECT-INFO to the current version with the cascade left in.docs/agents/and confirm the step-1 tie-break still migrates it (layout beats stamp). Runskills/upgrade-agent-os/SKILL.md. Verify withgit ls-files, neverls:.marvin/agents/,.marvin/PROJECT-INFO.md,.marvin/MEMORY.mdtracked;.docs/handbooks/*/index.mdtracked lowercase and noINDEX.mdremains under.docs/handbooks/(lslies on case-insensitive filesystems — this is the check that catches a skipped case-only rename);.docs/project-management/INDEX.mduntouched; every.docs/reports/file tracked at the same path under.marvin/reports/and none left under.docs/reports/, the upgrade's own report file beside them; no.docs/agents|.docs/PROJECT-INFO|.docs/marvinreference left in CLAUDE.md; history preserved (git log --followon a moved file);.marvin/CLAUDE.marvin.mdwritten by 4b andCLAUDE.mdsplit behind the gate, with its kit lines gone, its project lines kept and the import last. Assert the skill ranscripts/migrate-v0.21.0.shand thenscripts/migrate-v0.35.0.shfor the moves — both before any walked note's step — rather than moving files itself, that theirdeclined:/collision:lines reached the step-7 report file (.marvin/reports/<date>-upgrade-v<version>.md, committed with the restamp) in full and were not listed in chat, and that each migration's renames + reference edits landed in ONE commit of its own (git show --name-onlyon each holds both;git revertof the later one leaves locations and references consistent). Then, on a fresh copy of a v0.34.0 install with one untracked file in.docs/reports/, confirm the upgrade STOPS at step 3a (migrate-v0.35.0.shexit 2): only the step-7 report file is written and committed, naming that file, whilekit_versionand every guide in.marvin/agents/stay byte-identical and nothing moved. Then judge the reference edits the skill made itself — that is now the agent's half of the step, and the part a script cannot check: seed the fixture CLAUDE.md with a third-party URL containingdocs/agents/, an archived.docs/agents/<file>.md.baksibling that does not move, and a changelog line describing the old layout on purpose; all three must survive untouched while the live kit references are updated. The mechanical edge cases (interrupted rename, non-empty.docs/marvin/, occupied destination tracked or merely on disk, dirty tree, untracked or ignored report, unsafe repository state, consumer file in.docs/agents/) are fixtures inscripts/test-migrations.sh— step 1 already ran them; do not rebuild them by hand here. - (c2) v0.31.0 install → split: install v0.31.0 into a scratch repo from
git show v0.31.0:of this repo (or renderscripts/claude-core-history/v0.31.0.mdintoCLAUDE.mdover a v0.31.0.marvin/layout), add one project rule and one customised kit line, commit. Upgrade answering yes at the split gate: backup at.marvin/backups/v<target>/CLAUDE.md, kit lines removed, project/title/attribution lines kept, the customised line kept or namedcustomised-kit-line:, import last,issue_log_pathin PROJECT-INFO, the planner re-run printsresult=nothing-to-do, one commit. On a fresh copy answer no (and once give no answer): only the report file is written and committed, holding the planner report andclaude-md-split: declined|no-answer — upgrade stopped, no restamp. Re-run the yes result: a clean no-op. Also install over an existing kit-freeCLAUDE.md(append only the attribution item and the import) and over anAGENTS.md-only repo (stub with@AGENTS.mdabove the import,AGENTS.mduntouched), and an install over a pre-v0.33.0CLAUDE.mdSTOPS pointing atupgrade-agent-os. - (d) No-op: re-run the upgrade flow on (a)'s result, and again on (c)'s result. Verify both: clean
already at <version>chat line, no report file written, 0 moves performed,git status --shortempty, HEAD unchanged. - (e) Symlink refusal, deletes included: on a copy of (c)'s post-migration result, replace
.claude/agents/with a symlink to a directory OUTSIDE the repo holding the seven kit persona copies, and run step 4. It must refuse the WHOLE step naming the path, with every outside-repo file still present — the persona removal is step 4's only deletion, it leaves no backup by construction, andgit status --shortwould stay empty while the files were gone. Repeat withCLAUDE.mdsymlinked toAGENTS.md: same refusal, and it is documented as clearable, not as a bug. Repeat once more with.marvin/reportssymlinked to an empty directory OUTSIDE the repo, for the upgrade on that copy AND for a fresh install on (a)'s seed: both refuse before their first write (the install before step 1's migration), naming the path, and the outside directory is still empty. Last, on a fresh copy of (c)'s post-migration result, add a local line toCLAUDE.mdand hide it withgit update-index --assume-unchanged CLAUDE.md: step 4 refuses naming it (the Commit scope clean-path test's bit check), and no commit contains the line. Then close the crawl on (a)'s and (c)'s results: walk from.docs/index.mdand confirm every.mdoutsideproject-management/is reachable and no link resolves to.docs/.docs/.
- (a) Fresh install: seed a minimal repo (README + one manifest), run
- Report: static-gate result, per-scenario PASS/FAIL with the failed assertion and file diff when failing, and any judgment calls the skills forced (template wording gaps) — those are polish candidates, not blockers.
