Skip to content

Implementation Governance (TOGAF Phase G)

Auto-generated from USM feature contracts and system risks.

Feature Contracts (118)

FeatureContract IDDescriptionApplies AfterMust Have
usm/cli-config-outputsoutputs-configurableAll output paths are configurable via usmconfig.jsonGenerators 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 outputInvalid 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 removedgenerate:help-docs removed — use 'generate --only help-docs'; generate:togaf removed — use 'generate --only togaf'; generate:archimate removed — use 'generate --only archimate'
usm/docs-serve-port-checkport-check-clear-errorWhen the port is in use and --auto-port is not set, the user gets a clear, actionable error message.Error message includes the port number; Error message includes the process name/PID using the port (when detectable via lsof); Error message suggests --port N, --auto-port, or --restart as remedies; Exit code is non-zero
usm/docs-serve-port-checkauto-port-selectionWhen --auto-port is set, the next available port is selected automatically.Probes ports starting from the requested port, incrementing until one is free; Logs the selected port clearly (e.g. 'Port 5173 in use, using port 5174 instead'); Works for both --audience developer and --audience help; Does not probe more than 100 ports (safety limit)
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 must start on a configurable port with sensible defaultDefault port is 5173 (VitePress default); --port flag overrides default; Server accessible at http://localhost:<port>; Clear console output with URL and QR code for mobile review
usm/cli-docssidebar-matches-system-indexVitePress sidebar must reflect all features from system.usm indexEvery index entry appears in the sidebar; 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 updateFile watcher monitors .usm/ directory recursively; Only affected markdown regenerated (not full rebuild); 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 siteStatic 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 pathsOne 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 crashError 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-enrichenrich-preserves-human-editsEnrich must never overwrite fields that already have non-TODO contentFields 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 docsAll outputs derived from parsed .usm data; Duplicate $ids detected and warned; --check mode compares without writing
usm/cli-initinit-creates-configusm init must create a valid usmconfig.json at the specified output pathConfig 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 explicitlybuild() 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 fieldssummary 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 entryimport { defineFeature, defineService, writeFeature } from '@smithgray/usm' works; Types exported for IDE autocomplete
usm/internal-dsl-builderroundtrip-fidelityBuilder output parses back to the same objectyaml → parseUsm → deep-equals object
usm/cli-multi-lang-scanmanifest-detection-coverageScanner detects services from all supported language manifestspackage.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 languagesNext.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 languagesPrisma: 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.jsondetection.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 unchangedusm scan on a Node.js project produces same results as before; usmconfig.json without detection section uses defaults
usm/query-layerselector-and-predicatesThe grammar covers type selection, field comparison, existence, contains, and boolean compositionSelector 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 tracesMessage 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 safetyNo 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 modulesrc/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 onesCreates .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.jsonAll 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-scanPRESERVE_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
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.version is set to the installed version.version field written only after setup succeeds; Resulting system.usm validates against the schema
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 errorsUses 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 contentContent between USM:START and USM:END replaced with generated content; Content outside markers preserved exactly; If no markers exist, insert after first H1 heading
usm/gen-archimatearchimate-valid-xmlGenerated XML must conform to the ArchiMate 3.1 Open Exchange formatValid XML with proper namespace declarations; Elements organized by ArchiMate layer folders
usm/docs-experienceno-empty-stubsNo empty placeholder pages are emittedA 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 navdev-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 dumpNo 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 featureHelp 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 docsgetting-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 onlyNo 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 runbooksNo 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-feature-reviewreview-doc-has-approval-framingThe review.md must frame the spec for human approvalStarts 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 unchangedoverview.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 docEach 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 goesA '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 overrideDefault 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 projectExplicit '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 surfacesrulesFiles.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 usageEvery 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.jsonEvery 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 typesEach .usm type has a field table; Required vs optional clearly marked
usm/gen-help-referencemcp-reference-has-all-toolsMCP reference lists all 12 toolsAll 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 markdownH1 heading matches the .usm $id or name; Tables for flows, contracts, tests; No broken links
usm/gen-mermaidmermaid-valid-syntaxGenerated Mermaid files must parse without syntax errorsSpecial characters escaped (colons, pipes, brackets); Each diagram in its own .mmd file
usm/mkt-language-tabscarousel-shows-all-languagesAll 12 language logos visible at once in the carousel12 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 availableFrameworks 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 languageTypeScript: 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 frameworksTable with columns: Language, Manifest, Frameworks, Route Pattern; All 12 languages present; All 30+ frameworks listed
usm/mkt-language-tabsresponsive-carouselCarousel works on mobileLogo row scrolls horizontally on mobile; Selected logo clearly highlighted; Code example wraps on small screens
usm/gen-openapiopenapi-valid-specGenerated OpenAPI spec must validate against the OpenAPI 3.1 schemaAll 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 invocationDescription 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 promptopencode.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 configExisting 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 onboardingIron 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 itemsEmpty 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 filesLinks 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 caseagentsMd link matches agentsMd.md file; testSpecs link matches testSpecs.md file
usm/gen-roadmapmermaid-renders-in-vitepressMermaid code blocks render as diagrams, not raw textArchitecture 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 existsCursor 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 CodeShared iron-rules body in all tiers; Identical SKILL.md across runtimes
usm/structurizr-bridgeimport-never-destroysImport guards existing workExisting 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 DSLworkspace, 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 systemstructurizr accepted by --only; Output written under .usm-workspace/structurizr/
usm/structurizr-bridgeconservative-mappingMapping choices are documented and reversibleContainer 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-testspecstest-specs-runnableGenerated test specs must be syntactically valid Vitest filesEach 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-togaftogaf-phase-coverageGenerator must produce deliverables for phases A, B, C1, C2, D, E, G, HEach phase in its own markdown file; Phase A includes principles and stakeholders; Phase C1 includes data model from data .usm files
usm/agent-feedbackpolicy-respectedAll generated instructions and the MCP tool must honour the configured system.feedback.policyhuman-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 filesHard 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
usm/agent-feedbackinit-persists-policyusm init writes a valid feedback block and never leaves policy ambiguousBoth prompts answered or defaulted (human-gate) if skipped; Resulting system.usm passes schema validation
usm/agent-feedbacksmart-merge-preservedGenerator additions respect existing smart-merge guaranteesFeedback block rendered between USM markers only; Hand-written content outside markers unchanged
usm/mcp-contractscontracts-feature-onlyContracts tool only works on feature filesReturns 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 filesReturns 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 fileCount of files returned; Optional $type filter applied; Results sorted by path
usm/mcp-queryshared-evaluatorQuery grammar shared with the CLISelector 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 cappingNo 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 metadataMetadata 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 fieldsFinds 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 resultsCase-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 contentIncludes 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 contentReturns { 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 itReturns 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 diskValidates 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 onesFields 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 transitionsplanned → in-progress → built is valid; built → deprecated is valid; built → planned is rejected (use a new feature instead)
usm/schema-v1schema-three-typesThe schema must support exactly three file types: system, service, featureoneOf selects systemFile, serviceFile, or featureFile; 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 fieldssystemFile.additionalProperties is false; serviceFile.additionalProperties is false; featureFile.additionalProperties is false