A thin layer over existing tools: a unified lifecycle vocabulary + a versioned maturity rubric with drift detection + a structured manifest for the AI agent.
Working name. Subject to rename.
AI lifted the parallelism ceiling: instead of one primary stack (PHP), the same developer now juggles dozens of products at once across PHP, Node, Python, and Go. That creates two compounding pains:
- Operational friction. Every project has its own way to "bring up / shut down / rebuild / run tests." The depth and vocabulary of commands varies wildly from repo to repo.
- Quality drift. There is no objective measure of maturity. As the personal quality bar rises, older projects quietly fall behind, and there is no place to notice it.
vdx is built as a combine of ready-made tools. Custom code goes only into the things nobody else does — which is precisely why vdx exists.
| # | What | Why nothing off-the-shelf covers it |
|---|---|---|
| 1 | Normalized verb vocabulary up / down / build / test / check / fix |
task runners (mise/Task/just) don't prescribe a vocabulary |
| 2 | Versioned maturity rubric + drift engine | Soundcheck/Cortex/OpsLevel mutate the standard live; they don't work locally or on third-party repos |
| 3 | Shared-infra orchestration (Global Traefik as a dependency of up) |
no runner models cross-repo dependencies |
| 4 | A structured, executable manifest for the AI agent | AGENTS.md is deliberately prose; Claude Code skills (vdx-discover) react to project context |
What vdx will NOT do: — ship its own task runner (mise already does this polyglot and well); — claim "discover-and-cache" as a novel loop (Claude Code auto-memory already writes findings between sessions natively; vdx's novelty is that the recorded path is structured and executable, not prose).
Prerequisites:
- Node.js ≥ 20 (the CLI ships as ESM TypeScript via
tsx, no build step required). - mise — vdx delegates lifecycle execution to
mise run <verb>. - git — for
vdx auditrubric resolution (github.com/.../vdx-rubric-vodmal@<tag>) and forvdx publish.
Then pick one — same binary, same behavior, different trade-offs:
# A. Daily-use install (recommended for any repeated `vdx <verb>` workflow)
npm i -g @vodmal/vdx-cli
vdx audit
# B. Zero-install, run from anywhere (recommended for CI, one-shot trial,
# onboarding a teammate, or any "I just want to look")
#
# NOTE: `-p` is required because the binary `vdx` doesn't match the scoped
# package name `@vodmal/vdx-cli` — npx can't auto-infer the entry point.
npx -y -p @vodmal/vdx-cli vdx auditRule of thumb:
- Global when you run
vdxmany times per session — pays no per-invocation latency. - npx when you don't want a global install or you're in a clean / ephemeral environment (CI runner, fresh VM, someone else's laptop). Each
npxcall adds ~200–500 ms for resolve+stat.
Either way you get two binaries: vdx (the CLI) and vdx-mcp (the MCP server consumed by the Claude Code plugin — itself launched via npx from the plugin manifest, so plugin users never need a global install).
Run vdx doctor first. It checks your environment (Node version, vdx on PATH, git, mise, npm auth, container runtime, Claude Code plugin) and shows you exactly what to install or configure before using anything else.
# 1. Score any project against the owner baseline rubric
vdx audit
# 2. Generate a mise.toml that wires native scripts to vdx's 6 verbs
vdx init
# 3. Run lifecycle verbs (pass-through to `mise run <verb>`)
vdx build
vdx test
vdx check
vdx up # bring services up
vdx down # tear down
# 4. Publish a library (Node MVP; PHP/Python coming in Y.3)
vdx publish minor # bump, npm publish (with OTP), git commit+tag
# 5. Check your local environment (Node version, mise, git, docker, Claude Code plugin)
vdx doctorvdx init works deterministically on Node/PHP/Python/Go/Ruby projects. For unknown or meta (monorepo-with-subpackage) stacks, pass --stack <id> or — preferably — invoke vdx inside Claude Code with the plugin installed and let the vdx-discover skill bootstrap interactively.
vdx ships a Claude Code plugin (MCP server + skill + hook) so the agent can call vdx_build, vdx_audit, etc. natively and bootstrap unknown projects.
Inline marketplace (this repo serves the plugin directly):
…or point at a local clone: "/abs/path/to/vdx/marketplace". Then /plugin install vdx@vdx inside Claude Code.
The plugin gives you:
- MCP tools —
list_capabilities,vdx_up/down/build/test/check/fix,vdx_audit,vdx_record_success_path. vdx-discoverskill — auto-triggers when a project lacksmise.toml(or audits at L0/L1 onlifecycle-interface); walks native scripts, verifies them, records the success path.- PostToolUse hook — passive watermark of successful lifecycle runs into
~/.cache/vdx/last-success-path.log.
| Layer | Tool | Decision |
|---|---|---|
| Task runner | mise | D3 |
| Capability manifest | mise.toml + vdx meta-block; projected into AGENTS.md ## Commands |
D4 |
| Fact gathering for audit | OpenSSF Scorecard · Qlty CLI · MegaLinter (planned) | D5 |
| Scaffold-fix on own projects | copier (copier update, 3-way merge) — planned |
D5 |
| Claude Code packaging | plugin: MCP server + skill + hook | D6 |
Full rationale and open questions live in docs/decisions.md.
Familiar stack. vdx up → infra precheck → mise run up → native
command. Instant.
Unfamiliar stack via Claude Code. Through MCP, the agent knows the
project's 6 verbs and can invoke them without reading docker files.
vdx audit scores it against your rubric even in unfamiliar tooling.
No manifest yet. vdx falls back to detection — make/composer/
npm — and calls them directly. Once the agent finds a working success
path, a hook records it into mise.toml — the next run is instant.
Drift. The owner rubric moved forward → vdx audit shows the gap on
an old project. On your own repos, copier update applies the template
fixes; on third-party repos, it's a read-only report.
| Repo | What | Release cadence |
|---|---|---|
| vdx (this) | dev hub: research, spec, evaluator (cli/), Claude Code plugin (plugin/) |
changes often |
| vdx-rubric-vodmal | canonical owner-baseline rubric (vdx-rubric.yaml) |
semver tags (v0.3.0+) |
Manifest references in projects, e.g. baseline: github.com/VoDmAl/vdx-rubric-vodmal@v0.3.0, point at a specific semver
tag of the canonical repo. Sync rules between the two repos are documented
in CLAUDE.md ("External repo").
Spec D1–D12 ratified; core delivered in steps A–X.1.c within a single working session (see PROJECT_CHANGELOG.md for the full per-step log and HANDOFF.md for live state). Highlights:
- Step A — rubric v0.2 + draft spec (format, predicate DSL, drift algorithm).
- Step B — canonical repo
vdx-rubric-vodmalpublished on GitHub. - Step C — native evaluator (TypeScript, ~600 LOC under
cli/src/). - Step D — evaluator tuned via smoke tests on 3 reference projects.
- Step E —
vdx init: stack autodetect → mapping native tasks to the 6 verbs → generation ofmise.toml(no AGENTS.md — Claude Code users get thevdx-discoverskill from the plugin instead). - Step F — MCP server
vdx-mcpon stdio with 9 tools. - Step G — Claude Code plugin
vdx/plugin/(.claude-plugin/,.mcp.json, skill, hook). - Step H — dogfooding: vdx now has its own root
mise.toml, baseline audit. - Step I — stack detector sees depth-1 sub-packages (monorepo / dev hub).
- Step J —
applies_tofilter in rubric v0.2.2: stack-irrelevant axes getdrift_kind: excludedand don't count toward overall. - Step K —
[vdx].primary_subpackage+resolveSubpackageCtx(O31 closed). - Step L —
.github/workflows/ci.yml+npm testalias (ci L0→L3). - Step M —
matrix.node-version: [20, 22](ci L3→L4, first axis at max). - Step N — CLI published on npm as
@vodmal/vdx-cli;
the plugin is now marketplace-ready (
npx -y -p @vodmal/vdx-cli@latest vdx-mcp). - Step O — O33 closed (subpackage stack lift): for axes with
applies_to, the evaluator now uses the subpackage's stack instead of the root's. For vdx this removes theexcludedmask from 5 stack axes → an honest score. - Steps P–U — vitest harness (tests axis L0→L3), new
release-artifactaxis withapplies_whenlib/app gate (rubric v0.3.1, O34/O35 closed),vdx inittransparency + monorepo fallback (O39 closed), CLI bumped to v0.3.0 on npm. - Step V — D12 (
publish) accepted as 7th lifecycle verb after parallel landscape research;vdx publishlib-gated via the newapplies_whenpredicate, stack-specific defaults institutionalized inside vdx (npm/composer/twine/cargo/gem) so users don't learn ecosystem-specific commands. - Step X.1.a–X.1.c — D12 MVP for Node delivered and dogfooded:
executePublish()runs the full pipeline (bump →npm publishwith interactive OTP viastdio: 'inherit'→ git commit + tag, no push) and was used to ship @vodmal/vdx-cli@0.4.0 end-to-end.
| Artifact | File | Status |
|---|---|---|
| Onboarding for a new session | HANDOFF.md | current |
| Research journal (Decided / Open / Observed) | docs/decisions.md | current |
| Landscape of comparable tools (does / doesn't) | docs/landscape.md | current |
| Maturity rubric v0.2 (calibrated) | docs/maturity-rubric.md | current |
| Build-vs-adopt decision | docs/decision.md | current |
| Change log | PROJECT_CHANGELOG.md | maintained |
Internal research artifacts above are kept in Russian — they are the author's working notes. The outward-facing surface (this README, the CLI README, plugin README, and canonical-rubric repo) is English.
| Document | What it specifies |
|---|---|
| docs/specs/rubric-format.md | Format of the vdx-rubric.yaml owner baseline + predicate DSL + applies_to |
| docs/specs/manifest-format.md | The [vdx] block in mise.toml + AGENTS.md projection |
| docs/specs/overrides-format.md | .vdx-overrides.yml for per-project overrides |
| docs/specs/mcp-api.md | Contract of the vdx MCP server |
| docs/specs/drift-algorithm.md | Level computation + drift algorithm |
| docs/specs/vdx-rubric.example.yaml | Mirror of the canonical instance (for documentation) |
vdx audits itself against its own rubric. The declaration in
mise.toml is stack = "meta" (documentation + a nested CLI
in cli/).
Current position: overall L0. The real blocker is the ci axis (vdx
lacked GitHub Actions until step L; the supporting axes still need real
artifacts). Five stack-specific axes (tests, static-analysis, code-style,
dependency-hygiene, mock-infra) correctly receive drift_kind: excluded
under the meta stack and don't count toward overall. Lifecycle-interface
is at L2 (3 of 6 verbs: build, test, check — up/down/fix are absent by
design, vdx is not a service).
Next steps inside vdx: real tests (vitest), CI workflow, and sub-package-aware
predicates (O31) so the nested cli/ is audited as a Node project. The
full list of open questions lives in docs/decisions.md
and HANDOFF.md.