Skip to content

Implementation Governance (TOGAF Phase G) ​

Auto-generated from USM feature contracts and system risks.

Feature Contracts (200) ​

FeatureContract IDDescriptionApplies AfterMust Have
usm/cli-color-outputsymbols-coloredStatus symbols are colored in TTY output—✓ green; ✗ red; ⚠ yellow; ⊘ dim/yellow; → cyan
usm/cli-color-outputno-color-respectedNO_COLOR env var disables all color—NO_COLOR set → output is plain text; NO_COLOR unset → colors active in TTY
usm/cli-color-outputnon-tty-plainPiped/redirected output is plain text—stdout not a TTY → no ANSI codes; stderr not a TTY → no ANSI codes; spinner suppressed in non-TTY; progress bar suppressed in non-TTY; output remains grep-friendly
usm/cli-color-outputpalette-consistentColor semantics are consistent across all commands—success states green across init/scan/validate/generate/enrich/etc; error states red across all commands; warning states yellow across all commands; file paths and counts dim across all commands
usm/cli-color-outputdeps-cjs-compatibleAll new dependencies are CJS-compatible—picocolors ^1 (CJS); ora ^5 (last CJS major; v6+ is ESM); cli-progress ^3 (CJS); treeify ^0.1 (CJS); update-notifier ^5 (last CJS major; v7+ is ESM); package.json remains CommonJS (no module type field)
usm/cli-color-outputspinner-long-opsAnimated spinner during async operations—scan, enrich, generate show spinner with elapsed context; spinner clears and is replaced by result line on completion; spinner suppressed in non-TTY (plain log fallback)
usm/cli-color-outputprogress-batchProgress bar for batch file operations—generate writing N files shows progress bar with current/total; scan detecting services shows count progress; bar hidden in non-TTY
usm/cli-color-outputtree-file-listsFile lists rendered as tree view—Files written/skipped lists use tree connectors; nested .usm/ structure shown hierarchically; flat fallback in non-TTY
usm/cli-color-outputascii-bannerASCII art USM banner on no-args/help—usm with no args shows ASCII USM banner then help; banner suppressed in non-TTY
usm/cli-color-outputdid-you-meanSuggestions for unknown commands—usm scaan suggests scan via did-you-mean; suggestion shown via Commander built-in
usm/cli-color-outputupdate-notifierOne-line hint when a newer @smithgray/usm is published—checks npm registry in background, non-blocking; cached with 24h interval; hint only shown if newer version exists and in TTY
usm/cli-color-outputverbosity-flags--quiet and --verbose flags across commands—--quiet shows only errors and final summary; default shows current output level; --verbose shows timestamps, full paths, debug info
usm/cli-config-outputsoutputs-configurableAll output paths are configurable via usmconfig.json—Generators read paths from config, not hardcoded; Defaults work when config is missing or outputs section absent; All output types have config keys: workspace, docs, help_docs, archimate, togaf, openapi, tests, agents_md
usm/cli-config-outputsonly-flag-worksgenerate --only <target> runs only the specified output—Invalid target shows error with valid options; No --only runs all generators (backward compatible); Valid targets: docs, help-docs, togaf, archimate, openapi, tests, rules, agents-md
usm/cli-config-outputsno-colon-commandsgenerate:xxx commands are removed—generate:help-docs removed — use 'generate --only help-docs'; generate:togaf removed — use 'generate --only togaf'; generate:archimate removed — use 'generate --only archimate'
usm/config-validationconfig-validated-at-loadEvery place the CLI reads usmconfig.json validates it against the published usmconfig-v1.json schema; unknown outputs.* keys (and other schema violations) are hard errors, never silent defaults (issue #43).—Unknown keys under outputs produce a hard error naming the key and the supported set (workspace, docs, help_docs, archimate, togaf, openapi, tests, usm_source, agents_md); Unknown keys at other config levels error with the same shape (key named, schema section named); All three readers (usm init, usm scan, usm generate) go through one validated loader — no reader bypasses validation; A config that previously relied on silently-ignored keys now fails loudly at first use instead of writing to the wrong output directory; Malformed JSON fails with the parse error, not silent defaults (the current silent catch is removed)
usm/config-validationvalidate-config-flagusm validate gains a --config flag so consumers can gate config correctness in CI without side effects.—usm validate --config usmconfig.json reports valid/invalid with structured error paths, exit 0/1; Same validation as the load-time check (single source of truth for the rule set); No --config argument and no default usmconfig.json present → validate behaves exactly as today (back-compat)
usm/config-validationerrors-are-actionableThe load-time failure must tell the user exactly how to fix it, not just what broke.—Unknown-key error lists the valid keys for the section; Error shows the offending config file path; A suggested replacement is included for known renamed keys where one exists (e.g. api_docs → openapi)
usm/config-validationdocs-break-namespace-confusionDocs prevent the two documented failure modes behind issue #43: inventing config keys from spec-schema field names, and hunting for a YAML config format that does not exist.—config-reference states usmconfig.json is the only configuration format; no usm.yaml exists or is planned; config-reference states https://usm.dev/schema/v1.json is the schema for .usm spec files, a different artifact — do not derive config keys from it; A note where the two schemas share names (e.g. agent_context is a system.usm field, not a config key)
usm/config-validationbackward-compatibleProjects without a usmconfig.json, or with fully valid configs, behave byte-identically to 0.9.0.—No usmconfig.json → defaults used exactly as today (no new warnings); Valid config → identical output paths and identical generated artifacts; The usmconfig-v1.json schema file itself gains no breaking changes
usm/docs-ia-restructuresidebar-single-level-nestingThe sidebar renders within VitePress's single-level nesting limit: top-level groups with item lists only. Nested group structures are flattened at generation time with boundaries preserved as prefixed labels, never lost.—No group ever nests a group inside its items array — generation flattens Features sub-areas into sibling top-level collapsible groups (CLI, Generators, MCP Tools, Schema & Docs); Every rendered group title is intentional (never falls back to first-item text); Rendered sidebar verified structurally in a browser fixture: group titles match the intended IA
usm/docs-ia-restructurelabels-unique-and-humanEvery sidebar label is unique, human, and free of mechanical artifacts.—No duplicated area prefixes ('CLI CLI Color Output') — disk-discovered features reuse system.index display names when available, else title-case slug without area prefix; Area overview links are labelled '<Area> overview', not bare 'Overview' (no repeated labels across groups); Feature naming is consistent: the same feature renders the same label whether discovered from system.index or disk scan
usm/docs-ia-restructuresections-ordered-and-namedSidebar sections have a stable, audience-appropriate order and naming.—Dev order: Getting Started, Guides, Features, Project Management (Roadmap, Decision Register), Reference, Architecture, Source Map, Exports; Help order: Getting Started, Guides, Reference (user-facing pages only), Roadmap, Help (Language Support, Report Issue); Reference is its own top-level group (CLI Reference, MCP Tools, Configuration, Schema Reference) — not mixed into a group titled by its first item; Design section renders as 'Architecture' with its section labels intact
usm/docs-ia-restructurehelp-audience-purityHelp docs contain user-journey content only: feature build specs (flows/contracts/test internals) and the Decision Register are developer-docs content.—Help tree excludes features/ area pages (all areas, including cli) and design/decision-register; Help keeps Roadmap, reference pages, guides, getting-started, agent-setup-guide, editor setup, language support, feedback; Roadmap links that point at excluded feature pages degrade to plain text in the help tree (same guard pattern as package docs); Help sidebar never shows a group containing contract/flow/test internals; Agent Setup Guide appears in the help sidebar Getting Started group — the page renders in both audiences (universal package content) and must never be nav-orphaned in either
usm/docs-ia-restructureroadmap-currentThe roadmap stays current: every shipped feature appears, and stale statuses are corrected at the spec level — the roadmap page renders from system.usm, so fixing the source fixes the docs.—Features marked built in system.index have roadmap entries with shipped_in set (rules-files, docs-split, help-reference, config-outputs, mcp-write, this session's 0.9.x work); No roadmap item claims 'planned' for something already shipped; statuses match feature status; The 2026-09-27/28 consumer-blocker fixes appear as shipped items once released
usm/docs-serve-port-checkport-check-clear-errorWhen an EXPLICITLY requested --port is in use, the user gets a clear, actionable error message — explicit requests are strict.—Error message includes the port number; Error message includes the process name/PID using the port (when detectable via lsof); Error message suggests --auto-port (omit --port) or --restart as remedies; Exit code is non-zero
usm/docs-serve-port-checkauto-port-selectionWhen no --port is given, the next available port is selected automatically — concurrent instances never clash.—Default port base is 5173; if taken, probe incrementing until free (max 100 probes); Logs the selected port clearly (e.g. 'Port 5173 in use, using port 5174 instead'); Works for both --audience developer and --audience help; The announced URL is always the bound URL (USM probes and passes --strictPort to VitePress; bind failure fails loudly, never silently drifts)
usm/docs-serve-port-checkalready-serving-detectionRunning serve when a server is already up is handled gracefully.—PID file written to .usm-workspace/.vitepress.pid on start; On serve, detects existing server and prints its URL + PID; Does not start a second server unless --restart is passed; --restart kills the old server before starting a new one; PID file cleaned up on shutdown (SIGINT, SIGTERM, normal exit)
usm/docs-serve-port-checkwatch-mode-regeneration--watch keeps docs in sync with .usm changes automatically.—Watches .usm/ directory recursively for .usm file changes; Debounces regeneration (500ms after last change); Runs usm generate --only docs in-process (not a subprocess); Logs regeneration summary (file count); VitePress HMR picks up changed markdown files
usm/docs-serve-port-checkqol-commandsusm docs status, usm docs stop, --open, and graceful shutdown all work.—usm docs status prints server URL + PID or 'Not running'; usm docs stop kills the server and removes PID file; --open flag opens browser at the served URL; SIGINT/SIGTERM kills VitePress child and removes PID file; usm docs build is unaffected by all changes
usm/docs-serve-port-checkno-breakageExisting behavior is unchanged when the port is free and no server is running.—When port is free, behavior is identical to current (no extra output); usm docs serve --port 5173 works exactly as before when 5173 is free; usm docs build is unaffected; No new required dependencies (net, fs, child_process are all built-in)
usm/cli-docsserve-starts-on-configurable-portusm docs serve selects its port by audience need: auto-port by default (concurrent instances never clash), explicit --port strict.—Omitting --port auto-selects the next free port starting at 5173 and logs which port was chosen; Explicit --port N is strict: fails loudly with a clear, actionable error if N is taken; Bind-race in auto-port mode retries with a fresh probe (3 attempts) instead of failing; Announced URL always equals the bound URL (VitePress --strictPort); Server accessible at http://localhost:<port>; Clear console output with URL for review
usm/cli-docssidebar-matches-system-indexVitePress sidebar must enumerate every feature page in every area uniformly—Every index entry appears in the sidebar; Every feature page under docs/features/<area>/ appears, whether or not the area has an index.md (issue #36); Sidebar groups match .usm/features/ subdirectory names; Feature status (planned, active, deprecated) shown as badge; Services listed in sidebar from system.usm services[]
usm/cli-docshot-reload-on-usm-changeEditing a .usm file must trigger regeneration and browser update — of the FULL docs surface, not just developer markdown. Nav (config.mts) and the help-docs stream are part of the served contract.—File watcher monitors .usm/ directory recursively; Regeneration covers BOTH streams: developer docs AND help-docs tree; VitePress config.mts (sidebar/nav) refreshed on regeneration — write-on-change (idempotent), so the running server reloads nav exactly when it changed; Concurrent server startups self-organize: bind-race in auto-port mode retries with a fresh probe (3 attempts) instead of failing; generate --only help-docs preserves .vitepress/ across the tree rebuild (config.mts must not be deleted mid-serve); Sidebar renders zero dead links (every link resolves to a file on disk) and zero repeated links (dedup guard); VitePress HMR updates browser within 1 second; Console shows which file changed and was regenerated
usm/cli-docsbuild-produces-static-outputusm docs build must produce a deployable static site—Static HTML output in docs/.vitepress/dist/; All assets (CSS, JS, images) bundled; No server runtime required to serve output; Output works on Cloudflare Pages, GitHub Pages, Netlify, or any static host
usm/cli-docsunified-structure-is-flat-and-navigableAll docs in a single docs/ directory with predictable paths—One markdown file per .usm feature; Path pattern: docs/features/<area>/<feature>.md; Services at docs/services/<service>.md; No docs scattered across apps/ or .agents-workspace/
usm/cli-docsvitepress-missing-graceful-errorIf VitePress is not installed, show helpful error not a crash—Error message explains VitePress is optional dependency; Install command shown (pnpm add -D vitepress); Exit code 1 with clear message, not a stack trace
usm/cli-docsserve-identifies-project-and-url-shapedocs serve must make the served project and the docs URL shape unambiguous—Startup output prints the serving project name (system.usm identity, else package.json, else dir); Startup output prints the route shape /features/<area>/<slug> with the $system namespace dropped; MCP write tools return docs_url/docs_path so agents return correct links (issue #34)
usm/cli-docshelp-tree-layout-is-sibling-safeThe help-docs tree is a filtered derivative of the developer docs tree; the two output roots must be siblings (or at least the help root must not sit inside the docs root), because the filter walks the source tree and must never copy its own destination.—filterForHelpAudience rejects a helpRoot that is inside docsRoot (or equal to it) with a hard error naming both paths and the config keys to change (issue #47); The guard runs before any filesystem mutation — a bad layout fails fast without creating or deleting anything; No self-copy recursion is possible: copyFiltered never walks the help destination; Default sibling layout (.usm-workspace/docs + .usm-workspace/help-docs) unaffected; Configured nested layouts (e.g. docs: docs/ + help_docs: docs/help/) fail with an actionable error instead of ENAMETOOLONG
usm/cli-docshelp-output-path-honestEvery help-docs emission point reports the path files were actually written to — never a hardcoded default (issue #44).—generate --only help-docs success message names the resolved helpRoot (path.relative(root, helpRoot)), not the hardcoded .usm-workspace/help-docs/; Custom help_docs paths (e.g. docs/help/) are reflected in console output; docs serve/build --audience help likewise reports the configured path
usm/cli-docshelp-tree-derivation-gating-documentedThe help-docs tree is derived from already-generated developer docs; plain usm generate does not emit it. This gating is documented where consumers configure it.—--only help-docs help text states it filters the developer docs tree and requires a prior usm generate; config-reference documents which commands emit the help tree (generate --only help-docs, docs serve/build --audience help) and that plain generate does not (issue #44)
usm/cli-docshelp-build-derives-if-missingusm docs build --audience help auto-runs the filter pass when the help tree is absent, instead of erroring.—docs build --audience help with no existing help tree runs the filter pass first and then builds; docs build --audience help with an existing tree still rebuilds it (no stale-tree builds)
usm/cli-docsvitepress-on-demand-fetchDocs commands work on first run without any VitePress install: missing local + missing global → on-demand fetch via npx -y vitepress@1, transparently, mutating nothing; --no-fetch-vitepress restores the hard error for hermetic/CI environments.—Resolution order: project-local → global install → on-demand fetch (npx -y vitepress@1) → hard error only with --no-fetch-vitepress; Fetch mode prints one line stating what happened and how to make it permanent (npm i -D vitepress) — never silently; On-demand fetch pins vitepress@1 (no unpinned floating major); First-ever usm docs serve in a greenfield repo with no package.json works and mutates nothing (no package.json/node_modules side effects); Offline + no install + --no-fetch-vitepress → clear error naming the install command (today's behaviour preserved); spawn sites use the fetch-mode resolution (npx -y vitepress@1) consistently in both serve and build; Config-reference and getting-started document the fetch behaviour and the pinning option
usm/cli-enrichenrich-preserves-human-editsEnrich must never overwrite fields that already have non-TODO content—Fields with TODO: describe are filled; Fields with existing content are preserved; preserve_human_edits defaults to true
usm/cli-generategenerate-from-source-onlyGenerate must read .usm files directly — never derive docs from other docs—All outputs derived from parsed .usm data; Duplicate $ids detected and warned; --check mode compares without writing; Missing outputs outside git's tracked set are reported as (skipped: untracked) and do not fail --check — CI on a fresh clone can pass; missing tracked outputs still fail (issue #42); The skip summary states the count and remedy (run usm generate) so absence is never silent
usm/cli-initinit-creates-configusm init must create a valid usmconfig.json at the specified output path—Config has version: '1'; Config has name, services, shared, data, sources, outputs fields; Config does not overwrite unless --force is passed
usm/internal-dsl-builderbuilder-emits-valid-usmEvery build() result passes schema validation or reports errors explicitly—build() runs validateUsm and includes errors in the result; writeFeature refuses to write when valid is false; Generated YAML matches MCP write-tool serialization conventions
usm/internal-dsl-builderrequired-fields-enforcedThe builder surface mirrors the schema's required fields—summary and intent required before a valid build; $system and $service required at construction; flows get steps; contracts get must_have; tests get expect
usm/internal-dsl-builderexported-public-apiThe DSL ships as part of the package's public entry—import { defineFeature, defineService, writeFeature } from '@smithgray/usm' works; Types exported for IDE autocomplete
usm/internal-dsl-builderroundtrip-fidelityBuilder output parses back to the same object—yaml → parseUsm → deep-equals object
usm/mcp-setup-guidesmcp-setup-indexIndex page at /mcp-setup with a grid of all 35 editor cards—Grid layout of 35 editor cards grouped by category; Each card links to a per-editor setup page; Cards show editor name and one-line setup summary
usm/mcp-setup-guidesper-editor-pagesOne dedicated setup page per editor (35 total) with exact config—H1 with editor name; Exact MCP config snippet (JSON/TOML/YAML/CLI command depending on editor); Restart-required flag where applicable; Rules/skills file installation for editors that support always-on hooks; Link back to the index page
usm/mcp-setup-guidesrules-files-coverageEditors with always-on hook support document the rules file install—opencode: .opencode/skills/usm-workflow/SKILL.md + .opencode/usm-instructions.md; Claude Code: CLAUDE.md + .claude/skills/usm-workflow/SKILL.md; Cursor: .cursor/rules/usm.mdc + .cursor/rules/usm-always.mdc; Copilot: .github/copilot-instructions.md + .github/instructions/usm-iron-rules.md; Codex: AGENTS.md; Other editors: note if always-on hooks are not supported
usm/mcp-setup-guidestool-logos-top-10Marketing site ToolLogos updated with top 10 editors—Top 10: Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, JetBrains, opencode, Codex, Zed, Continue; SVG paths from Simple Icons where available, fallback Terminal icon otherwise
usm/mcp-setup-guideshelp-audienceSetup pages are in the help docs (public audience), not developer docs—Pages sit under .usm-workspace/docs/mcp-setup/; Accessible at docs.usm.dev/mcp-setup; Sidebar entry under Getting Started
usm/cli-multi-lang-scanmanifest-detection-coverageScanner detects services from all supported language manifests—package.json → Node.js/TypeScript/JavaScript; pyproject.toml or requirements.txt → Python; Cargo.toml → Rust; go.mod → Go; pom.xml or build.gradle → Java/Kotlin; .csproj or .sln → C#/.NET; Gemfile → Ruby; composer.json → PHP; mix.exs → Elixir; Package.swift → Swift; build.sbt → Scala; CMakeLists.txt or Makefile → C/C++; Framework detected from dependencies in manifest
usm/cli-multi-lang-scanroute-detection-coverageScanner detects routes from 30+ frameworks across all languages—Next.js: app/page.tsx, app/route.ts (existing); Express: app.get/post/put/delete in .js/.ts files; FastAPI: @app.get/post decorators in .py files; Flask: @app.route decorators in .py files; Django: path() patterns in urls.py; Go chi/gin/echo: r.GET/POST and router.HandleFunc patterns; Go net/http: http.HandleFunc patterns; Rust Axum: .route() calls; Rust Actix: #[get/post] macros; Rust Rocket: #[get/post] attributes; Spring Boot: @GetMapping/@PostMapping/@RequestMapping annotations; Javalin: app.get/post calls; Quarkus: @GET/@POST + @Path annotations; ASP.NET Core: [HttpGet]/[HttpPost] attributes; ASP.NET Minimal: app.MapGet/MapPost; Rails: get/post/resources in config/routes.rb; Sinatra: get '/path' do in .rb files; Laravel: Route::get/post in routes/web.php; Symfony: #[Route] attributes; Slim: $app->get/post in .php files; Phoenix: get/post in router.ex; Vapor: routes.get/post in .swift files; Akka HTTP: path/endpoints in .scala files; Play: GET /path in conf/routes; Tapir: endpoint.get/post in .scala files; Crow: CROW_ROUTE macro in .cpp files; Drogon: registerHandler in .cpp files; Pistache: router.get/post in .cpp files
usm/cli-multi-lang-scandata-model-detection-coverageScanner detects data models from ORMs across languages—Prisma: schema.prisma (existing, TypeScript); SQLAlchemy: class definitions in models.py (Python); Django ORM: class definitions in models.py (Python); GORM: struct definitions with gorm tags (Go); Diesel: table! macros in schema.rs (Rust); Hibernate: @Entity annotations in .java (Java); Entity Framework: DbSet properties in DbContext (C#); ActiveRecord: class definitions inheriting ApplicationRecord (Ruby); Eloquent: class definitions extending Model (PHP); Ecto: schema definitions in .ex files (Elixir)
usm/cli-multi-lang-scanconfig-extensibleDetection rules are configurable in usmconfig.json—detection.manifests array with {pattern, language, frameworks?} objects; detection.routes array with {framework, pattern, method_group, path_group} objects; detection.data_models array with {orm, pattern, model_pattern?} objects; Defaults cover all supported frameworks; users can add custom patterns
usm/cli-multi-lang-scanbackward-compatibleExisting Node.js/TypeScript scanning unchanged—usm scan on a Node.js project produces same results as before; usmconfig.json without detection section uses defaults
usm/cli-multi-lang-scandetector-file-formatDetector files in .usm/detectors/*.yaml are validated against a detector-v1.json schema before use—Each detector declares $id, kind (service|framework|routes|data-schema|infrastructure), manifest glob, language, runtime; Framework detectors declare frameworks[] with name + string-contains detect rule; Route detectors declare routes.extensions + routes.patterns[] (regex, methodGroup, pathGroup) OR routes.script (mutually exclusive); Invalid detector files are skipped with a warning, not an abort
usm/cli-multi-lang-scandual-extension-surfacesUsers can extend detection through either usmconfig.json or .usm/detectors/ files, with the same expressiveness—usmconfig.json detection.manifests / detection.routes / detection.data_models / detection.infrastructure arrays (existing accepted decision, unchanged); .usm/detectors/*.yaml files as a second, auto-discovered source; Both surfaces accept the same field shapes (manifest, frameworks, routes patterns, data model patterns); Detector files support routes.script for convention-based frameworks; usmconfig.json detection.routes supports script too
usm/cli-multi-lang-scanorchestrator-generalizedService detection is driven by detector manifests, removing the package.json hardcode in structural.ts—A service directory is detected if ANY detector manifest glob matches a file in it (not only package.json); A Go app with go.mod and no package.json produces a service.usm (no 'No package.json found' warning); A Zig app with build.zig.zon and no package.json produces a service.usm; The existing Python pyproject.toml and Docker docker-compose passes become built-in detectors, not special-case code
usm/cli-multi-lang-scaninfrastructure-extensibleInfrastructure detection is extensible beyond Terraform via detectors—Built-in Terraform detector preserves usm scan infrastructure output exactly; detection.infrastructure array in usmconfig.json (new, mirrors detection.manifests shape); Infrastructure detector files accepted in .usm/detectors/; CloudFormation, Pulumi, CDK detectable via user-supplied detectors without code change
usm/cli-multi-lang-scanprecedence-and-overrideDetector sources merge with a deterministic precedence so users can override built-ins—Built-in detectors are the lowest precedence (seeded from current MANIFESTS/ROUTE_PATTERNS/Prisma/Terraform tables); .usm/detectors/ files override built-ins by detector $id; usmconfig.json detection section is highest precedence (overrides both built-ins and detector files); A usmconfig.json with no detection section and no .usm/detectors/ dir produces identical results to the current scanner (backward compatible)
usm/cli-multi-lang-scanbackward-compatible-existing-implementationsExisting USM projects with usmconfig.json and .usm files continue to scan identically—usm scan on a Node.js/Next.js project with no detection section and no detectors dir produces the same .usm output as before this feature; Existing PRESERVE_FIELDS / UPDATE_FIELDS smart-merge behaviour unchanged; Existing CLI flags (--force, --routes, --merge) unchanged in name and default; The existing manifest-detection-coverage and route-detection-coverage contracts from the original spec remain satisfied by the migrated built-in detectors
usm/pkg-universal-docspackage-ships-universal-docsThe npm package ships a universal docs-source/ directory with the onboarding pages every consumer repo needs; file list includes it so it lands in the tarball.—package files[] includes docs-source/; shipped set covers agent-setup-guide.md, getting-started.md, and editor-setup/ (index + per-editor guides); shipped pages contain no repo-specific content (no Smith & Gray ids, no internal links)
usm/pkg-universal-docsconsumer-overridePrecedence is total: consumer repo docs-source/ wins wholesale; generated reference_pages beat package content on filename collision; package content is fallback only.—consumer repo with docs-source/ gets byte-identical output to today (no package content copied); consumer repo without docs-source/ gets the package set copied into the docs output tree; package file never overwrites a generated page with the same output name; merge is skipped in --check mode (no writes)
usm/pkg-universal-docsnav-lights-up-automaticallyExisting dead-link guards light up automatically once package content is present — no guard changes required for consumers to see onboarding nav.—homepage renders the Getting Started link when the package page was copied (hasPage guard); sidebar shows Editor Setup and Agent Setup Guide entries when the pages exist (docExists guard); consumer trees without the package content keep today's guarded behavior (no regression)
usm/pkg-universal-docslink-discipline-in-consumer-treeAll shipped pages pass the full-link discipline in the CONSUMER output tree: every link resolves, sidebar and content, both docs audiences.—no relative or .md-suffixed hrefs in shipped page content; {"crawl of a consumer fixture tree":"0 dead links, 0 duplicate links, both audiences"}; cross-page links limited to pages guaranteed by the copy step (editor-setup/, agent-setup-guide, getting-started) or guarded at generation time
usm/pkg-universal-docsidempotent-universal-docsPackage docs merge is deterministic and repeatable: same inputs produce byte-identical output trees.—second usm generate run produces byte-identical docs output; removed package files do not leave orphans in a clean tree; existing consumer-repo behavior unchanged for every other generator pass
usm/query-layerselector-and-predicatesThe grammar covers type selection, field comparison, existence, contains, and boolean composition—Selector maps to $type filtering (features→feature etc, all→any); = != on strings; > < >= <= on numeric fields (array lengths, version); ~ substring contains case-insensitive; has field for existence/non-empty; and or not with parentheses, standard precedence (not > and > or)
usm/query-layerfriendly-errorsParse failures produce actionable messages, never raw stack traces—Message names the token and position and what was expected; Unknown fields resolve to missing (has is false, comparisons false) rather than erroring
usm/query-layerread-only-and-cappedQuery never writes; MCP results are capped for context safety—No file writes on any query path; MCP default limit 50 with total + truncated in the response
usm/query-layerone-evaluator-two-surfacesCLI and MCP share a single parser/evaluator module—src/query module is the only implementation; MCP response includes path so agents can usm_read hits directly
usm/cli-scaffold-projectscaffold-project-creates-structureScaffold-project must create all directories and files without overwriting existing ones—Creates .usm/ directory tree; Skips existing files (reports ⊘); Produces valid YAML for each file
usm/cli-scaffoldscaffold-valid-templateScaffold must produce a file that validates against v1.json—All required fields present; File not overwritten if it already exists
usm/cli-scanscan-preserves-editsSmart-merge preserves human-edited fields (summary, intent, decisions, flows, contracts, tests) on re-scan—PRESERVE_FIELDS are kept if non-default; UPDATE_FIELDS ($last_updated, paths, port, depends_on) are overwritten; --force bypasses merge
usm/upgradeversion-comparedUpgrade reads the installed package.json version and system.usm.version and reports stale or up-to-date.—Installed version resolved from the USM package.json (not the project's); Absent system.usm.version treated as 0.0.0 (stale); Stale vs up-to-date clearly reported; --check message for a never-aligned project is actionable: names 'usm upgrade --apply' as the opt-in act (issue #46)
usm/upgradecapabilities-detectedEvery registry capability is checked; missing and recommended ones are reported with a setup hint.—All registry entries run through detect(); Missing recommended capabilities surfaced prominently; Each missing capability shows its setup hint
usm/upgradesetup-non-destructiveSetup never overwrites an existing block.—detect() returns true → capability skipped entirely; No existing config field is overwritten
usm/upgradeversion-bumped-on-completionAfter a successful apply, system.usm.usm_version is set to the installed version — including the already-aligned case (issue #46).—usm_version field written only after setup succeeds; Resulting system.usm validates against the schema; --apply with nothing left to set up (capabilities already configured) still stamps usm_version when stale — recording alignment, not silently doing nothing; Requested targets that fail to apply exit non-zero in every path (explicit-targets and recommended-missing alike); The already-aligned stamp is reported ('aligned at <version>') so the change is visible, not silent
usm/upgradenon-interactive-safeNon-interactive modes work without prompts and are CI-safe.—--apply runs all recommended missing capabilities with defaults, no prompts; --check reports only and exits non-zero if stale; Non-TTY defaults to report-only (no hanging on stdin)
usm/cli-validatevalidate-against-v1-schemaValidate must use the v1.json schema with Ajv and report all errors—Uses Ajv with allErrors: true; Reports path and message for each error; Exit code 1 if any file fails
usm/vitepress-home-feedback-schemahomepage-reference-firstHomepage is a clean technical reference, not a marketing duplicate.—Short intro paragraph (2-3 sentences); Quick Stats table (feature count, service count, package count); Quick Start commands (copy-pasteable); Prominent link cards to Schema Reference, Getting Started, Roadmap; Spec-first workflow Mermaid diagram; No principle cards, benefit sections, or "Sound familiar?" content; Single link to usm.dev for marketing content; Sidebar fully visible (no collapsed groups by default)
usm/vitepress-home-feedback-schemafeedback-dual-modeFeedback button works for both humans and agents.—Visible "Report Issue" link in nav bar and/or sidebar; Dedicated feedback page with two clear paths; Human path: pre-filled GitHub issue URL with template (title, body, page context); Agent path: MCP tool instructions (usm_report_feedback with page + .usm context); VitePress editLink points to .usm source on GitHub
usm/vitepress-home-feedback-schemaall-content-generatedAll new content is generated from .usm files — no hand-authored output pages.—Homepage content derived from system.usm; Feedback page generated by markdown generator; Cross-links derived from system.usm index and feature refs; Smart-merge preserved; re-running generate is idempotent
usm/vitepress-home-feedback-schemano-breakageExisting pages, generators, and the docs build remain healthy.—usm validate passes with 0 errors; usm generate produces all existing pages plus new ones; usm docs serve / usm docs build succeed; Existing feature/service/reference pages unchanged in substance
usm/vitepress-schema-polishfully-generated-from-usmAll new homepage/schema/getting-started content is generated from .usm files and schema/v1.json — no hand-authored output pages that can drift.—Homepage hero/cards/example derived from system.usm + schema, not hardcoded literals; Schema reference fully derived from schema/v1.json; Smart-merge preserved; re-running generate is idempotent
usm/vitepress-schema-polishschema-reference-comprehensiveThe schema reference answers 'what does this field do?' for every major type.—Covers system, service, feature, feedback file types plus shared sub-schemas (flow step, contract, test, decision, usage, options); Each field shows description/intent, type, required/optional, constraints, YAML example, generator/MCP/validation impact, best-practice; Scannable tables + collapsible detail blocks; cross-links to examples
usm/vitepress-schema-polishno-breakageExisting pages, generators, and the docs build remain healthy.—usm validate passes with 0 errors; usm generate produces all existing pages plus the new ones (no dead links, none removed); usm docs serve / usm docs build succeed; Existing feature/service/reference pages unchanged in substance
usm/vitepress-schema-polishdark-mode-and-mobileThe site looks correct in both themes and on mobile.—Mermaid diagrams switch theme with VitePress light/dark; Layout, tables, code blocks responsive on narrow viewports; Typography/contrast consistent across themes
usm/vitepress-schema-polishsmart-merge-preservedGenerator changes never clobber hand-edits.—Pages still written between USM markers; content outside markers untouched; Re-generating over an existing tree does not discard human edits
usm/vitepress-schema-polishlightweightThe site stays fast with no heavy runtime dependencies.—Mermaid loaded via CDN only; no new heavy client bundles; VitePress local search retained; build time does not regress materially
usm/gen-agentsmdagents-md-preserveAGENTS.md generator must never destroy hand-written content and must be idempotent—Content between USM:START and USM:END replaced with generated content; Content outside markers preserved exactly; If no markers exist, insert after first H1 heading; Repeated runs are byte-identical — no trailing-newline accumulation (issue #32)
usm/gen-agentsmdagents-md-reference-pointerAGENTS.md includes a compact USM reference block so agents in consumer repos know where authoritative USM documentation lives — without injecting dogfood content into the repo's own docs.—USM section lists: docs.usm.dev (tool reference), usm.dev (user docs), schema URL, and the upstream tracker; Instructs agents to prefer MCP tools (usm_list/usm_read/usm_search) for spec context, USM site for tool reference; Zero repo-specific dogfood content in the block — same links for every consumer; Idempotent and marker-preserved like the rest of the generated section
usm/gen-archimatearchimate-valid-xmlGenerated XML must conform to the ArchiMate 3.1 Open Exchange format—Valid XML with proper namespace declarations; Elements organized by ArchiMate layer folders
usm/gen-content-blockscontent-block-schemaThe schema defines a content block type with variants for every VitePress feature needed for rich docs.—Block types: heading, paragraph, code, mermaid, tabs, callout, table, steps, cards, badge, divider; code block supports language, title (VitePress code-group), and line highlighting; mermaid block outputs a fenced code block with language mermaid (rendered by VitePress mermaid plugin); tabs block contains tab entries with label + content blocks (nested); {"callout block supports types":"info, tip, warning, danger (VitePress containers)"}; table block has headers array and rows array of arrays; steps block has ordered items with optional inline code; cards block has items with title, description, optional icon/link (VitePress features grid); badge block supports type info/tip/warning/danger and text
usm/gen-content-blocksreference-pages-on-systemsystem.usm can declare reference pages with inline content or runtime sources.—reference_pages array field on system.usm schema (optional); Each entry has id, title, audience (public or internal, default internal), optional content array (content blocks), optional source (detectors, schema, or config); source detectors renders from the detector registry at generation time; source schema renders from v1.json (delegates to existing generateSchemaReference logic); source config renders from usmconfig-v1.json (delegates to existing generateConfigReference logic); Pages with audience public appear in help docs; internal only in developer docs
usm/gen-content-blocksreference-blocks-on-featuresFeature specs can carry user-facing reference content that survives the help filter.—reference array field on feature schema (optional); Each reference entry has heading, audience (public or internal), content array (content blocks); Reference blocks rendered after standard feature doc sections (summary, intent, flows); Help filter keeps reference blocks with audience public; drops audience internal; Feature docs without reference array are unchanged (backward compatible)
usm/gen-content-blocksgeneric-rendererOne rendering function converts content blocks to VitePress markdown — no per-page bespoke functions for content.—renderContentBlocks function is the single entry point; Every block type has a renderer; unknown block types produce a warning and are skipped; Nested blocks (tabs contain blocks, cards may contain blocks) render recursively;
usm/gen-content-blocksdelete-hardcoded-contentHardcoded content functions and constants are removed and their content migrated to specs.—LANGUAGE_SUPPORT constant deleted from markdown.ts; generateLanguageSupportDoc replaced by reference_pages source detectors rendering; generateAgentSetupGuide replaced by reference_pages agent-setup inline content; Hardcoded prose in generateGettingStartedDoc migrated to reference_pages getting-started; Data Model Detection hardcoded table migrated to a reference block on usm/cli-multi-lang-scan; generateConfigReference and generateSchemaReference preserved (they read JSON schema files, which ARE the source of truth)
usm/gen-content-blocksbackward-compatible-existing-specsExisting .usm files without content blocks or reference_pages generate identical docs.—Feature specs without reference array produce the same doc output as before; system.usm without reference_pages does not produce the deleted hardcoded pages (they are opt-in); All existing tests pass without modification; Spec-driven generators (generateCliReference, generateMcpReference, generateMarkdown, generateOpenApiSpec, generateTestSpecs, generateArchiMateModel, generateMermaid architecture/ER/deps) are unchanged
usm/gen-content-blocksaudience-filter-block-levelThe help-doc filter operates at content-block granularity, not section granularity.—simplifyFeatureDoc updated to filter content blocks by audience field; Blocks with audience public or no audience field survive the help filter; Blocks with audience internal are dropped from help docs; Contracts, tests, implementation, decisions continue to be stripped (developer-only)
usm/gen-content-blocksuniversal-not-usm-specificThe content-block system works for any USM project, not just USM's own docs.—Any project system.usm can declare reference_pages with inline content or detector/schema/config sources; Any project feature specs can carry reference blocks; The generic renderer has no USM-specific content baked in; A project with no reference_pages and no reference blocks generates the same docs as before this feature
usm/docs-experienceno-empty-stubsNo empty placeholder pages are emitted—A templated section page is emitted only when the source service carries data for it; Sidebar entries match emitted pages one-to-one (no dead links); A CLI never gets ui, production-deployment, or observability pages
usm/docs-experiencetogaf-in-navThe real TOGAF deliverables are reachable from the technical docs nav—dev-docs sidebar has an Architecture group linking the Phase A-H deliverables; help audience omits the Architecture section; No parallel orphaned togaf directory
usm/docs-experiencecontent-widthReference content uses the viewport, not VitePress's 688px default—--vp-layout-max-width overridden to ~1280 or wider; Code blocks and tables render full-width; Applies to every consumer site on their next generate
usm/docs-experiencehomepage-is-navigationThe homepage is a navigation surface, not a metrics dump—No At-a-glance, Identity, or Who-its-for body markdown on index.md; A features grid of cards links into the primary doc sections; Hero actions retained
usm/docs-experienceaudience-voice-distinctHelp and technical audiences read differently for the same feature—Help feature page leads with when-to-run and example output; Technical feature page is spec-faithful (full flows, contracts, tests); Same source .usm, two render paths
usm/docs-experienceno-handwritten-driftNo hand-written drift in generated docs—getting-started install version derived from package.json; VitePress sitemap enabled on both audiences
usm/gen-docs-splithelp-docs-only-built-featuresHelp docs only include features with status built (or visibility public)—Features with status planned or in-progress are excluded from help docs; Features with visibility: public are included regardless of status; Features with visibility: internal are excluded from help docs
usm/gen-docs-splithelp-docs-simplified-contentHelp docs feature pages show summary + intent + flows only—No contracts section in help docs; No tests section in help docs; No implementation section in help docs; No decisions section in help docs (or simplified to decision + rationale only)
usm/gen-docs-splithelp-docs-no-sensitive-infoHelp docs exclude deployment details and operations runbooks—No deployment.md in help docs; No operations section; No build commands or secrets in help docs
usm/gen-docs-splitdeveloper-docs-unchangedDeveloper docs remain exactly as before (full detail)—All features included (planned, in-progress, built); Full contracts, tests, decisions, implementation; Deployment and operations pages
usm/gen-docs-splithelp-docs-user-journey-onlyHelp docs contain the user journey only — internal tooling pages (code-navigator, orphan-files, spec-coverage) and the design/ architecture section are contributor material and live exclusively in developer docs.—code-navigator.md, orphan-files.md, spec-coverage.md absent from help docs; design/ section absent from help docs (sidebar group too); getting-started, agent-setup-guide, CLI/MCP/schema/config references, roadmap, language-support, feedback present in help docs; composed user-docs guides present in help docs sidebar; developer docs keep all of the above (full detail, unchanged)
usm/gen-feature-reviewreview-doc-has-approval-framingThe review.md must frame the spec for human approval—Starts with a one-line intent summary in plain language; Flows section reads as a procedure, not a data table; Contracts section is a checklist, not a table; Tests section uses given/when/then format; Ends with an implementation plan section (primary file, status)
usm/gen-feature-reviewreview-doc-is-separate-from-overviewreview.md is a new file, overview.md is unchanged—overview.md continues to be generated with current format; review.md is generated alongside overview.md; Both files share the same output directory
usm/gen-feature-reviewdecisions-included-when-presentWhen a feature has decisions[], they appear in the review doc—Each decision shows the decision text and rationale; Decisions frame as 'Why this approach' section
usm/feedback-upstream-routingscope-branch-explicitEvery generated feedback protocol explicitly branches on bug scope before stating where it goes—A 'Where does the bug live?' distinction rendered in every rules file; Project scope: existing policy behaviour unchanged; USM-tool scope: upstream URL named literally with the gh -R command
usm/feedback-upstream-routingupstream-default-and-overrideThe upstream tracker has a default and a system.feedback override—Default upstream: https://github.com/Smith-Gray-Pty-Ltd/usm/issues; Optional feedback.upstream_tracker field in system.usm overrides it; Schema update is optional-field-only (no breaking change)
usm/feedback-upstream-routingno-misfilingThe protocol must forbid filing USM tool bugs against the consuming project—Explicit 'never file USM tool bugs in this repo's tracker' rule; usm_report_feedback human-gate draft mentions upstream routing for tool bugs
usm/feedback-upstream-routingone-source-many-surfacesScope routing text is generated from a single code path into all surfaces—rulesFiles.ts generateFeedbackProtocol is the single source; Docs feedback page and MCP tool text stay consistent with it
usm/gen-help-referencecli-reference-has-all-commandsCLI reference page includes all CLI commands with usage—Every feature in features/cli/ with usage field appears in the reference; Each command shows usage examples and options table
usm/gen-help-referenceconfig-reference-from-schemaConfig reference is generated from usmconfig-v1.json—Every field in usmconfig-v1.json appears in the reference; Each field shows type, description, and default
usm/gen-help-referenceschema-reference-covers-all-typesSchema reference covers system, service, feature, and data types—Each .usm type has a field table; Required vs optional clearly marked
usm/gen-help-referencemcp-reference-has-all-toolsMCP reference lists all 12 tools—All read tools (8) and write tools (4) appear in the table; Each tool shows summary and when to use
usm/gen-markdownmarkdown-gfmMarkdown output must be valid GitHub-flavored markdown—H1 heading matches the .usm $id or name; Tables for flows, contracts, tests; No broken links
usm/gen-markdownmarkdown-single-writer-per-pathEach output path must have exactly one generating pass, and output must be a pure function of the .usm inputs—No generator derives output by reading the file it is about to overwrite; generateDataModelDoc owns .usm-workspace/docs/data/models.md (ER section composed in); Area overviews write to the root .usm-workspace/docs/features/ — never apps/<svc>/.usm-workspace/; usm generate --check converges immediately after a clean usm generate
usm/gen-mermaidmermaid-valid-syntaxGenerated Mermaid files must parse without syntax errors—Special characters escaped (colons, pipes, brackets); Each diagram in its own .mmd file
usm/gen-mermaider-section-is-pureThe ER diagram section must be a pure function of the Prisma schema, never of prior on-disk output—buildERDiagramSection(root) reads only packages/db/prisma/schema.prisma; generateDataModelDoc is the sole writer of .usm-workspace/docs/data/models.md; No generator reads a file it is about to overwrite
usm/mkt-language-tabscarousel-shows-all-languagesAll 12 language logos visible at once in the carousel—12 language logos in a horizontal row; Logos at 50% opacity, selected at 100%; Default: TypeScript selected; Clicking a logo updates frameworks + code example below
usm/mkt-language-tabsframework-displayFrameworks shown as chips with logo where available—Frameworks with Simple Icons logo: logo + name; Frameworks without logo: name only as text chip; All frameworks for the selected language visible
usm/mkt-language-tabscode-example-per-languageRoute detection code example shown for each language—TypeScript: app.get('/users', handler); Python: @app.get('/users'); Go: r.GET('/users', handler); Rust: .route('/users', get(handler)); Java: @GetMapping('/users'); C#: [HttpGet('users')]; Ruby: get '/users' do; PHP: Route::get('/users', ...); Elixir: get('/users', UserController, :index); Swift: routes.get('users') { req in }; Scala: path('users') { get { handler } }; C++: CROW_ROUTE(app, '/users')
usm/mkt-language-tabsdocs-grid-comprehensiveHelp docs page lists all languages and frameworks—Table with columns: Language, Manifest, Frameworks, Route Pattern; All 12 languages present; All 30+ frameworks listed
usm/mkt-language-tabsresponsive-carouselCarousel works on mobile—Logo row scrolls horizontally on mobile; Selected logo clearly highlighted; Code example wraps on small screens
usm/mkt-mock-interfaces-v2browser-vitepress-lookBrowser mock looks like the real VitePress docs site—Left sidebar with grouped nav sections (Getting Started, Features, etc.); Top bar with USM logo, search placeholder, Report Issue link; Content area renders real doc structure: H1, Usage code block, How it works numbered steps, Guarantees checkbox criteria
usm/mkt-mock-interfaces-v2ide-file-explorerIDE mock has a file explorer sidebar showing .usm files being created—Left file explorer panel with tree of project files; .usm files appear with green + badge as the agent writes them; Explorer syncs with the agent's file-write actions
usm/mkt-mock-interfacestwo-mock-interfacesTwo side-by-side animated mock interfaces below the Works with your client section—Left mock = agentic IDE/chat with agent prompts and responses referencing USM; Right mock = browser window showing specs/docs loading for the corresponding command; Both mock interfaces animate (typing, streaming responses, page loads); Layout is responsive (stacks on mobile, side-by-side on desktop)
usm/mkt-mock-interfacesusm-references-in-chatAgent chat references USM tools and specs—Agent mentions usm_read, usm_write_feature, or similar MCP tools; Agent references a feature spec before coding; Spec-first workflow is visible in the dialogue
usm/mkt-mock-interfacesbrowser-specs-loadingRight mock browser shows specs/docs loading in response to the agent action—Browser URL bar updates to a docs/spec URL; Page content loads progressively (skeleton then content); Loaded content matches the spec the agent just wrote or read
usm/mkt-mock-interfacessynced-timingThe two mocks are loosely synced so the chat action appears to trigger the browser load—Chat completes an action then browser loads the corresponding spec; Cycle repeats with a different command/spec pair
usm/gen-openapiopenapi-valid-specGenerated OpenAPI spec must validate against the OpenAPI 3.1 schema—All routes present as paths with correct HTTP methods; Security schemes for auth-required routes; TypeScript types generated for request/response schemas
usm/opencode-integrationskill-description-is-the-nudgeThe skill's frontmatter description must carry the workflow trigger by itself, since it is the only part visible before invocation—Description front-loads trigger keywords and filenames (.usm, feature, spec); Description states when to invoke: before starting feature work, when unsure a change needs a spec, when the session has drifted; Body contains the full checklist including read-before-code, draft-before-build, show-human-review, update-status-after
usm/opencode-integrationinstructions-injected-every-requestThe iron-rules file must be registered in opencode.json instructions so opencode appends it to every system prompt—opencode.json instructions array contains .opencode/usm-instructions.md; The file is short (≤ ~30 lines) — iron rules only, no system description; Content is the same workflow taught by all other rules files
usm/opencode-integrationuser-config-preservedThe generator must never damage user-authored opencode config—Existing instructions entries preserved in order; No other top-level field added, removed, or modified; $schema field preserved; valid JSON output; works when opencode.json does not yet exist (creates minimal file) and when it exists at root or .opencode/
usm/opencode-integrationdrift-countermeasureThe per-message reinforcement must explicitly address mid-session drift, not just initial onboarding—Iron rules phrased as per-message self-checks (e.g. 'Before ANY code change: does a .usm spec exist for this?'); Skill description mentions re-anchoring a drifted session
usm/gen-roadmaproadmap-only-generated-when-non-emptyRoadmap page is only generated when system.usm has roadmap items—Empty roadmap array → no roadmap.md generated; Non-empty roadmap → roadmap.md with table
usm/gen-roadmapsidebar-no-dead-linksSidebar must not contain links to non-existent files—Links to /risks only if risks.md exists; Links to /roadmap only if roadmap.md exists; Feature links only if the feature doc file exists
usm/gen-roadmapsidebar-case-matches-filesSidebar links must match actual file name case—agentsMd link matches agentsMd.md file; testSpecs link matches testSpecs.md file
usm/gen-roadmapmermaid-renders-in-vitepressMermaid code blocks render as diagrams, not raw text—Architecture page shows rendered diagram; Other mermaid blocks render properly
usm/gen-rules-filesall-tools-coveredAll tools covered with always-on iron rules where a per-message mechanism exists—Cursor usm.mdc plus usm-always.mdc; Claude CLAUDE.md plus skills SKILL.md; Codex AGENTS.md detail only; Copilot instructions plus usm-iron-rules.md; opencode SKILL.md plus wired instructions
usm/gen-rules-filestwo-tier-enforcement-parityIron rules from one shared function; SKILL.md identical for opencode and Claude Code—Shared iron-rules body in all tiers; Identical SKILL.md across runtimes
usm/gen-source-mappingbidirectional-mappingThe generator builds a bidirectional file-to-feature-to-service-to-module mapping from existing spec data.—Reads service.usm modules name, purpose, and paths for directory-level grouping; Reads feature.usm implementation.primary and implementation.test_code for file-level ownership; Reads feature.usm routes file_path for route source files; Walks the filesystem within each service paths directory to enumerate actual files; Matches each file to a module by directory, a feature by implementation.primary, and a route by file_path
usm/gen-source-mappingmultiple-views-one-mappingMultiple views render from one SourceMap data structure, each as a reference_pages source.—file-tree source renders a directory tree with descriptions, grouped by service and module; coverage-matrix source renders a table of file, module, owning feature, spec status; orphan-report source renders only files with no governing feature spec; All views render through the generic content-block renderer as reference pages
usm/gen-source-mappinguniversal-not-usm-specificThe source mapping generator works for any USM project, reading the project's own specs.—No USM-specific content baked into the generator; Reads the project's service and feature specs, not hardcoded file lists; A project with no reference_pages source-mapping entries produces no output (backward compatible); File descriptions come from module purpose and feature summary, not from the generator
usm/gen-source-mappingbackward-compatibleExisting projects without source-mapping reference_pages entries are unaffected.—No reference_pages entries with file-tree/coverage-matrix/orphan-report sources means no output; All existing tests pass without modification; No new schema fields required — uses existing modules, implementation.primary, routes file_path
usm/gen-source-mappingorphan-detectionFiles in the codebase not claimed by any feature spec are identified as orphans.—A file in a service paths directory with no matching implementation.primary is an orphan; Orphan files are excluded from exclude patterns (node_modules, dist, .git, etc.); The orphan-report view lists orphans grouped by service and module
usm/structurizr-bridgeimport-never-destroysImport guards existing work—Existing system.usm or service files are never overwritten without --force; --dry-run lists planned writes without writing; Invalid or non-workspace JSON fails with a clear message
usm/structurizr-bridgeexport-valid-dslExported workspace.dsl is well-formed Structurizr DSL—workspace, model and views structure with balanced braces; Quotes in names and descriptions escaped; System name from identity.name, containers from services, components from features with $service set
usm/structurizr-bridgetarget-registeredExport participates in the standard generate target system—structurizr accepted by --only; Output written under .usm-workspace/structurizr/
usm/structurizr-bridgeconservative-mappingMapping choices are documented and reversible—Container becomes service with type api by default, or database, cache, queue when technology suggests it; Unmappable detail preserved in summary text, never dropped silently
usm/gen-technical-designadapt-to-project-typeThe generator must adapt to any project type — a CLI tool with no database, a library with no deployment, a monorepo with multiple services. Sections with no data are suppressed entirely, not rendered as empty stubs.—Each of the 13 pages is only rendered if its data source exists; The sidebar only includes links to rendered pages; A CLI-only project produces no Database Design, API Design, or Deployment Architecture pages; No page contains an empty section with no content
usm/gen-technical-designone-source-many-viewsThe technical design document is a view of the same .usm data as TOGAF, feature docs, and source mapping. It must not duplicate or hardcode content — it renders from specs.—All content is derived from .usm files, schema, or declared content blocks; No USM-specific content hardcoded in the generator; No content duplicated from TOGAF or feature docs — both read from the same specs independently
usm/gen-technical-designcontent-block-enrichmentsystem.usm can declare inline content blocks for any Design section via a new design_pages[] field (parallel to reference_pages[]). These enrich the structured data with prose that doesn't fit schema fields.—design_pages[] entries have id, title, audience, and either content[] (content blocks) or source (structured data); Inline content blocks render AFTER structured data on the same page; Sections without design_pages entries still render from structured data alone
usm/gen-technical-designprose-escapingAll prose from specs must be escaped via escapeProse before rendering to prevent VitePress Vue template compilation errors from unescaped angle brackets.—All spec-authored prose passed through escapeProse; All table cell content passed through escapeTableCell or escCell; Mermaid diagram blocks are exempt (they use their own escaping)
usm/gen-technical-designsidebar-data-drivenThe sidebar structure is generated from data availability, not hardcoded. Groups and pages appear only when their underlying data exists.—Design group only includes pages that were rendered; Project Management group only appears if roadmap, features, or decisions exist; Developers group only includes reference pages that have data; Exports group only appears if TOGAF or ArchiMate outputs exist
usm/gen-technical-designdecision-registerThe Decision Register consolidates all decisions from features, services, and system principles into one page — the single source of truth for what was decided and why.—All feature decisions[] included with source feature $id; All service decisions[] included with source service $id; System principles[] rendered as architecture decisions; Each decision shows ID, decision, status, rationale, alternatives, consequences
usm/gen-technical-designnav-template-structureThe generated sidebar follows a fixed five-group template structure that applies to any
project. The template defines which groups exist, which pages go in each group, and which
content sections each Design page contains. Groups and pages are suppressed when their data
source doesn't exist, but the structure itself is the standard template.—Getting Started group: Home, Getting Started; Design group: 13 section pages (Project Overview, Requirements, System Architecture, Module Design, Database Design, API Design, Security Design, Deployment Architecture, Testing Strategy, Maintenance & Monitoring, Backup & Recovery, Risks & Mitigation, Future Enhancements) — only rendered pages appear; Project Management group: Roadmap, Features (grouped by service/area), Decision Register; Developers group: Source Map, Test Coverage, Spec Coverage, API Reference, CLI Reference, Configuration (only pages with data appear); Exports group: TOGAF Phases, ArchiMate Model (collapsed); Each Design page has a defined set of content sections (3rd-level outline) that the generator renders — these are the page's TOC, not separate sidebar links
usm/gen-testspecstest-specs-runnableGenerated test specs must be syntactically valid Vitest files—Each flow maps to a describe block; Each test maps to an it block with setup and expect; Aggregated specs import per-feature files
usm/gen-testspecsvitest-specs-from-flows-testsTest specs are a pure, collision-free function of the .usm inputs—One output spec file per feature $id; Source path resolution is exact $id parsing, not substring matching (issue #37 class); Two features must never target the same output path; Generated specs are valid Vitest files
usm/gen-togaftogaf-phase-coverageGenerator must produce deliverables for phases A, B, C1, C2, D, E, G, H—Each phase in its own markdown file; Phase A includes principles and stakeholders; Phase C1 includes data model from data .usm files
usm/gen-user-docspersonas-first-classsystem.usm gains personas[] — id, name, description. Flows and steps gain optional actor (persona id, or 'system'/'agent') and optional surface (e.g. ui, cli, api).—personas[] validates: unique ids, non-empty name; actor values either reference a declared persona id or are system/agent; validate fails on unknown persona references (typo protection); existing specs without personas/actor validate unchanged
usm/gen-user-docsjourneys-vs-pipelinesA flow is a journey when its actor (flow-level or step-level) references a persona; otherwise it is a pipeline and behaves exactly as today.—flows with default (no) actor default to system and stay in the developer stream; journeys render in user docs; pipelines never do; step-level actor overrides flow-level default
usm/gen-user-docsuser-docs-composedNew user-doc generator composes guides from personas and journeys — never by filtering developer content.—one guide page per journey: task-oriented title from flow name, ordered steps; steps with actor=system/agent rendered as 'the system …' prose, persona steps as instructions; per-persona navigation grouping (Guides for <persona>); generation is idempotent and deterministic
usm/gen-user-docse2e-from-journeystests[] gains optional flow reference; journey tests emit Playwright e2e skeletons alongside existing Vitest output.—tests with flow referencing a journey emit a valid Playwright .spec.ts under tests/auto-generated/e2e/; output path derives from exact feature $id — collision-free (issue #37 class); tests without flow ref continue to generate Vitest specs unchanged
usm/gen-user-docshelp-composition-replaces-subtractionFeature pages in help docs are composed from summary, intent, and public journey guides; the subtraction filter is deprecated but stays functional for system-level pages.—help feature pages contain no contracts/tests/implementation sections; help feature pages embed the journey guides relevant to public personas; existing --audience help still runs and produces a valid site (non-feature pages unchanged); no user-visible regression for projects with no personas defined
usm/gen-user-docsbackward-compatibleProjects that never declare personas get byte-identical generated output to the previous version.—all existing generators unchanged when no personas/journey actors present; schema changes are additive and optional-only; existing .usm files validate with no edits required
usm/agent-feedbackpolicy-respectedAll generated instructions and the MCP tool must honour the configured system.feedback.policy—human-gate mode instructs the agent to ask the human and forbids autonomous writes; direct-to-feedback mode instructs the agent to call usm_report_feedback; direct-to-github mode is only offered/emitted when feedback.github_auth is true
usm/agent-feedbackno-adhoc-tracking-filesThe protocol must explicitly forbid agents from inventing their own bug/issue tracking files—Hard rule present in every rules file: NEVER create ad-hoc tracking files at repo root; Canonical feedback location named: .usm/feedback (overridable via feedback_dir)
usm/agent-feedbackfeedback-schema-validatedFeedback entries are first-class .usm files validated against the schema—$type: feedback recognised by the v1 schema; Required fields: kind (bug|improvement|question), severity, summary, status, reported_by; usm_validate accepts a feedback file
usm/agent-feedbackinit-persists-policyusm init writes a valid feedback block and never leaves policy ambiguous—Both prompts answered or defaulted (human-gate) if skipped; Resulting system.usm passes schema validation
usm/agent-feedbacksmart-merge-preservedGenerator additions respect existing smart-merge guarantees—Feedback block rendered between USM markers only; Hand-written content outside markers unchanged
usm/mcp-contractscontracts-feature-onlyContracts tool only works on feature files—Returns error if file is not a feature; Returns contractCount and full contracts array; Each contract includes id, description, must_have
usm/mcp-flowsflows-feature-onlyFlows tool only works on feature files—Returns error if file is not a feature; Each flow includes id, name, description, stepCount, steps
usm/mcp-listlist-returns-metadataList must return path, id, type, version, and summary for each file—Count of files returned; Optional $type filter applied; Results sorted by path
usm/mcp-queryshared-evaluatorQuery grammar shared with the CLI—Selector maps to $type filtering; Absent fields make predicates false, never errors; Friendly parse errors naming token and position
usm/mcp-queryread-only-cappedRead-only with context-safe capping—No file writes on any query path; Default limit 50 with total and truncated in the response
usm/mcp-readread-returns-full-dataRead must return both the full parsed object and metadata—Metadata includes id, type, version, summary; System files include featureCount, serviceCount; Feature files include flowCount, contractCount, testCount
usm/mcp-referencesreferences-deep-walkReferences must walk the entire object tree, not just top-level fields—Finds references in $system, $service, depends_on, see_also, and nested objects; Returns context field showing where the reference was found; Results sorted by path
usm/mcp-searchsearch-top-10Search returns the top 10 most relevant results—Case-insensitive by default; Score based on occurrence count; Excerpt from summary around first match
usm/mcp-summarysummary-lightweightSummary must return only metadata — not the full file content—Includes id, type, version, last_updated, summary; System files include featureCount, serviceCount; Feature files include flowCount, contractCount, testCount; Service files include runtime, port, depends_on
usm/mcp-validatevalidate-inline-or-pathValidate must accept either a file path or inline YAML content—Returns { valid, errors } structure; Errors include path and message; File-not-found returns valid: false
usm/mcp-writedraft-validates-before-returningdraft_feature must validate the spec before returning it—Returns validation_status: valid or invalid; If invalid, returns structured errors with field paths; YAML is only generated if validation passes
usm/mcp-writewrite-is-atomicwrite_feature must not leave partial/corrupt files on disk—Validates full file before writing; Writes to temp then renames (atomic on POSIX); Returns error if write fails — original file untouched
usm/mcp-writeupdate-preserves-unspecified-fieldsupdate_feature merges provided fields without losing existing ones—Fields not in the update payload are preserved; Array fields are replaced, not merged (explicit intent); $id, $type, $schema are immutable — cannot be changed via update
usm/mcp-writestatus-transitions-are-saneupdate_feature_status enforces valid status transitions—planned → in-progress → built is valid; built → deprecated is valid; built → planned is rejected (use a new feature instead)
usm/mcp-writewrite-returns-docs-urlWrite and update tools return the canonical docs link so agents don't guess ports or URL shapes (issue #34)—write_feature, update_feature and update_feature_status include docs_path on success; docs_url is a full localhost URL when a docs server port is recorded; docs_hint explains how to get a live URL when none is running
usm/schema-v1schema-three-typesThe schema must support every file type advertised by the UsmFileType union, with the discriminator enum and oneOf in agreement—oneOf selects systemFile, serviceFile, featureFile, dataFile, or feedbackFile; Every $type in commonFields.enum has a matching oneOf/$defs branch; Common fields: $schema, $id, $type, $version, summary; $id pattern: ^[a-z0-9][a-z0-9-]/[a-z0-9][a-z0-9-]$; Flow steps require id and action; Contracts require id and description; Tests require id and expect
usm/schema-v1schema-additional-properties-falseEach file type must set additionalProperties: false to prevent undocumented fields—systemFile.additionalProperties is false; serviceFile.additionalProperties is false; featureFile.additionalProperties is false; dataFile.additionalProperties is false