Skip to content

Production readiness validation

Production readiness validation

Validated against agents v0.2.45 on 2026-05-08. Evidence came from source review, the existing Rust test suite, and temporary-directory CLI probes that kept the real home/config/cache state untouched.

Validation commands

Terminal window
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test
cargo test --test production_readiness
cargo build --release
pnpm --dir site install --frozen-lockfile
pnpm --dir site build

Targeted probes also covered:

  • agents --quiet remote list
  • agents --no-sync apply --dry-run
  • repeated agents --no-sync apply
  • legacy managed copy manifest entries followed by skills deactivate and skills remove
  • agents --no-sync skills find deploy

Review clarification: row 49 validates import of external subagent files into agents’ internal canonical representation. The canonical multi-harness frontmatter in the lockfile docs is an internal storage/rendering format, not an external standard that third-party sources are expected to publish.

Resolved issues

IDBehaviorsSeverityIssueResolutionRegression coverage
PRI-0017P1--quiet was not global because several commands printed directly, bypassing ui::quiet.Normal command output now routes through quiet-aware UI helpers; warnings/errors remain visible.quiet_suppresses_remote_list_plain_output
PRI-00217P1apply --dry-run swept .agents/tmp and could pre-pull before planning.Dry-run skips temp sweeping and auto-sync pre-pull.apply_dry_run_preserves_tmp_dirs
PRI-00318P2Repeated apply changed .agents/manifest.toml because applied_at was regenerated and the file was always rewritten.Manifest entries preserve prior timestamps when path/kind/skill/harness/target are unchanged, and manifest writes are skipped when serialized content is unchanged.repeated_apply_keeps_manifest_content_stable
PRI-00437, 39P1Immediate skills add installs were not recorded in the manifest, so a following skills deactivate or skills remove could leave symlinks on disk.skills add now records installed symlinks in the manifest as soon as it writes them.immediate_add_then_remove_uninstalls_skill_target
PRI-00544P2skills find printed Vercel-style npx skills output instead of agents install commands.Non-interactive search results now emit agents skills add <source> --skill <name> lines.non_interactive_result_formats_agents_install_command
PRI-00633P3Registry fallback was reported as logging duplicate warnings when registry lookup errored.Rechecked the current source and confirmed there is a single warning path.Source review; covered by single remaining warning path.
PRI-00737, 39P1skills deactivate and skills remove left legacy managed copies on disk.Both paths now use manifest EntryKind to dispatch symlinks to uninstall_path and legacy copies to uninstall_copy.deactivate_removes_legacy_copy_install, remove_removes_legacy_copy_install

Dependency decisions

  • serde_yaml = "0.9" is retained for the current release line. The parser is limited to local/cached Markdown frontmatter parsing and native harness frontmatter rendering, and changing it would risk subtle YAML formatting differences across skill and subagent files. Treat the deprecated crate as an accepted short-term release risk until a maintained parser migration can be tested against the existing import/render fixtures.

One-by-one validation

#AreaStatusValidation notes
1Fresh installPassinit --scaffold resolves a target, writes agents.toml, agents.lock.toml, .gitignore, .agents/, initializes git, and soft-fails only the initial commit if git identity is missing.
2Fresh clonePassinit <git-url> clones into the target, refuses non-empty targets, ensures state dirs, and writes the pointer/machine config.
3Custom repo pathPassinit --repo <path> writes the XDG pointer when the target differs from the default repo path.
4Machine profilesPass--profiles is parsed as comma-delimited values and persisted to .agents/machine.toml; apply uses profile_match for skills, subagents, and instructions context.
5Existing repo detectionPassstatus resolves the repo, reads lockfile/manifest/machine config, reports profile and health details, and does not write state.
6Missing repo recoveryPasspaths::resolve_repo errors with the expected pointer/default locations and run agents init recovery text.
7Global quiet modePassNormal output routes through quiet-aware UI helpers; machine-readable skills list --json / --names output remains direct by design.
8Verbose diagnosisPassstatus emits repo and manifest details through ui::detail, which is gated by --verbose; list output also adds scope/profile detail in verbose mode.
9Read-only safetyPassis_mutating leaves status, skills list/show/find, validate, project list, remote list, instructions diff/show, and subagents list unlocked.
10Mutating serializationPassMutating commands acquire RepoLock; integration test apply_prints_wait_message_when_repo_lock_is_held validates lock waiting.
11Fail-fast lock modePassRepoLock::acquire(..., no_wait = true) returns a clear contention error; unit coverage validates the branch.
12Remote setupPassremote add refuses non-git repos, adds origin, pushes the current branch with upstream tracking, and rolls back origin when push fails.
13Remote protectionPassremote add checks for an existing origin and bails with the current URL before changing git config.
14Manual syncPasssync delegates to git pull --rebase --autostash and push; it does not stage, commit, or rewrite lockfile content itself.
15Offline tolerancePassAuto-sync pre-pull and push detect common offline errors, warn, and keep local state.
16Clean applyPassapply materializes active, profile-matching skills, subagents, and instructions across resolved harnesses.
17Apply dry runPassDry-run previews planned writes without sweeping .agents/tmp, writing files, updating manifests, creating backups, or auto-syncing.
18Idempotent applyPassRepeated apply keeps managed files correct and preserves manifest content when the desired state is unchanged.
19Harness filteringPassapply -a <harness> builds a target harness set and skips unmatched skill/subagent outputs.
20Project filteringPassapply --project <alias> only processes entries whose project matches that alias.
21Unregistered projectPassMissing project aliases are collected, warned, and skipped while other entries continue.
22Matching skill copy cleanupPassinstall_skill_symlink hashes existing real dirs/files against the canonical target and auto-heals matching content.
23Conflicting skill copy cleanupPassinstall_skill_symlink deletes existing harness-local skill copies, and remove_cross_tool_skill_copies removes stale .agents/skills aliases.
24Forced non-skill conflict recoveryPass--force moves foreign instructions or subagent paths to <name>.bak.<unix-ts> before installing managed output.
25Symlink-only installsPassapply installs skills, rendered instructions, and rendered subagents into harness paths as symlinks.
26Legacy copy cleanupPassLegacy managed copy entries are removed during apply/deactivate/remove and future installs are symlinks.
27Skill add happy pathPassskills add fetches, snapshots remote sources, upserts the lockfile, installs into harnesses, and auto-commits when sync is enabled.
28Skill add list modePass with caveat--list avoids lockfile/snapshot/manifest/harness changes, but still acquires the mutating command lock and may pre-pull/fetch into temp state.
29Vercel compatibilityPassnormalize_all_flag makes --all imply wildcard skill selection, wildcard harnesses, and -y.
30Explicit harness installPassExplicit -a values are preserved in the lockfile and used for install targeting.
31Profile-gated skillPass--profile is stored on the lock entry and apply skips machines without a matching profile.
32Project-scoped skillPass--project requires a registered alias, stores it in the lockfile, and installs under that project root.
33Unknown skill fallbackPassRegistry fallback exists and uses the skills.sh download endpoint for missing GitHub skills; registry lookup failures now produce one warning.
34OpenClaw risk gatePassSource::parse_with rejects openclaw/* sources unless the explicit risk flag is set.
35Skill updatePassskills update compares upstream SHAs/hashes, refetches drifted snapshots, updates tree_sha, and leaves unchanged entries alone.
36Deactivated update skipPassDeactivated entries are excluded from bulk updates and explicitly skipped with a warning when named.
37Skill deactivatePassDeactivation removes symlink installs and legacy managed copies using the manifest entry kind.
38Skill activatePassskills activate flips active = true, writes the lockfile, and invokes apply to re-materialize eligible entries.
39Skill removePassRemoval deletes lockfile entries, managed snapshots, symlink installs, and legacy managed copies.
40Missing skill removePassTarget resolution bails before removal when a named skill is missing in the selected scope.
41Pipe-friendly listPassskills list switches stdout to names-only when stdout is not a TTY; skills remove reads whitespace-separated names from stdin.
42JSON list contractPassskills list --json suppresses the banner/UI output and emits the versioned JSON envelope with all documented fields.
43Skill showPassskills show resolves the canonical skill dir and prints only SKILL.md, erroring if the snapshot is missing.
44Registry searchPassNon-interactive search emits pipe-friendly agents skills add <source> --skill <name> commands; the TTY picker still installs selected results interactively.
45Bulk importPassBulk import adopts eligible local skills, dedupes across harness dirs, skips managed/plugin skills, and can adopt orphan snapshots.
46Instructions importPassimport --instructions writes the template, adds [instructions], and records existing output files in the manifest.
47Instructions validationPassvalidate checks template identifiers against declared profiles plus reserved harness/hostname identifiers.
48Instructions conflictPassNon-interactive apply refuses foreign instruction files; interactive apply offers skip/cancel/overwrite, and --force backs up then writes.
49Subagent addPasssubagents add imports external Claude-format Markdown, converts it into agents’ internal canonical Markdown, stores lockfile metadata, and renders native harness outputs. The internal canonical format is not treated as a required external import format.
50Self-updateCode-validatedupgrade calls the updater, reports updated or already-at-latest, and refreshes the update-check cache. It was not run as a probe because it can replace the local binary.