Implementation Governance (TOGAF Phase G)
Auto-generated from USM feature contracts and system risks.
Feature Contracts (118)
| Feature | Contract ID | Description | Applies After | Must Have |
|---|---|---|---|---|
| usm/cli-config-outputs | outputs-configurable | All 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-outputs | only-flag-works | generate --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-outputs | no-colon-commands | generate: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/docs-serve-port-check | port-check-clear-error | When 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-check | auto-port-selection | When --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-check | already-serving-detection | Running 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-check | watch-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-check | qol-commands | usm 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-check | no-breakage | Existing 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-docs | serve-starts-on-configurable-port | usm docs serve must start on a configurable port with sensible default | — | Default 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-docs | sidebar-matches-system-index | VitePress sidebar must reflect all features from system.usm index | — | Every 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-docs | hot-reload-on-usm-change | Editing a .usm file must trigger regeneration and browser update | — | File 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-docs | build-produces-static-output | usm 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-docs | unified-structure-is-flat-and-navigable | All 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-docs | vitepress-missing-graceful-error | If 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-enrich | enrich-preserves-human-edits | Enrich 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-generate | generate-from-source-only | Generate 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 |
| usm/cli-init | init-creates-config | usm 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-builder | builder-emits-valid-usm | Every 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-builder | required-fields-enforced | The 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-builder | exported-public-api | The 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-builder | roundtrip-fidelity | Builder output parses back to the same object | — | yaml → parseUsm → deep-equals object |
| usm/cli-multi-lang-scan | manifest-detection-coverage | Scanner 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-scan | route-detection-coverage | Scanner 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-scan | data-model-detection-coverage | Scanner 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-scan | config-extensible | Detection 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-scan | backward-compatible | Existing 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/query-layer | selector-and-predicates | The 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-layer | friendly-errors | Parse 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-layer | read-only-and-capped | Query 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-layer | one-evaluator-two-surfaces | CLI 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-project | scaffold-project-creates-structure | Scaffold-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-scaffold | scaffold-valid-template | Scaffold must produce a file that validates against v1.json | — | All required fields present; File not overwritten if it already exists |
| usm/cli-scan | scan-preserves-edits | Smart-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/upgrade | version-compared | Upgrade 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/upgrade | capabilities-detected | Every 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/upgrade | setup-non-destructive | Setup never overwrites an existing block. | — | detect() returns true → capability skipped entirely; No existing config field is overwritten |
| usm/upgrade | version-bumped-on-completion | After 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/upgrade | non-interactive-safe | Non-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-validate | validate-against-v1-schema | Validate 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-schema | homepage-reference-first | Homepage 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-schema | feedback-dual-mode | Feedback 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-schema | all-content-generated | All 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-schema | no-breakage | Existing 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-polish | fully-generated-from-usm | All 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-polish | schema-reference-comprehensive | The 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-polish | no-breakage | Existing 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-polish | dark-mode-and-mobile | The 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-polish | smart-merge-preserved | Generator 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-polish | lightweight | The 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-agentsmd | agents-md-preserve | AGENTS.md generator must never destroy hand-written content | — | 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 |
| usm/gen-archimate | archimate-valid-xml | Generated XML must conform to the ArchiMate 3.1 Open Exchange format | — | Valid XML with proper namespace declarations; Elements organized by ArchiMate layer folders |
| usm/docs-experience | no-empty-stubs | No 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-experience | togaf-in-nav | The 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-experience | content-width | Reference 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-experience | homepage-is-navigation | The 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-experience | audience-voice-distinct | Help 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-experience | no-handwritten-drift | No hand-written drift in generated docs | — | getting-started install version derived from package.json; VitePress sitemap enabled on both audiences |
| usm/gen-docs-split | help-docs-only-built-features | Help 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-split | help-docs-simplified-content | Help 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-split | help-docs-no-sensitive-info | Help 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-split | developer-docs-unchanged | Developer 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-review | review-doc-has-approval-framing | The 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-review | review-doc-is-separate-from-overview | review.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-review | decisions-included-when-present | When 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-routing | scope-branch-explicit | Every 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-routing | upstream-default-and-override | The 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-routing | no-misfiling | The 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-routing | one-source-many-surfaces | Scope 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-reference | cli-reference-has-all-commands | CLI 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-reference | config-reference-from-schema | Config 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-reference | schema-reference-covers-all-types | Schema reference covers system, service, feature, and data types | — | Each .usm type has a field table; Required vs optional clearly marked |
| usm/gen-help-reference | mcp-reference-has-all-tools | MCP 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-markdown | markdown-gfm | Markdown 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-mermaid | mermaid-valid-syntax | Generated Mermaid files must parse without syntax errors | — | Special characters escaped (colons, pipes, brackets); Each diagram in its own .mmd file |
| usm/mkt-language-tabs | carousel-shows-all-languages | All 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-tabs | framework-display | Frameworks 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-tabs | code-example-per-language | Route 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-tabs | docs-grid-comprehensive | Help 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-tabs | responsive-carousel | Carousel works on mobile | — | Logo row scrolls horizontally on mobile; Selected logo clearly highlighted; Code example wraps on small screens |
| usm/gen-openapi | openapi-valid-spec | Generated 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-integration | skill-description-is-the-nudge | The 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-integration | instructions-injected-every-request | The 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-integration | user-config-preserved | The 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-integration | drift-countermeasure | The 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-roadmap | roadmap-only-generated-when-non-empty | Roadmap 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-roadmap | sidebar-no-dead-links | Sidebar 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-roadmap | sidebar-case-matches-files | Sidebar links must match actual file name case | — | agentsMd link matches agentsMd.md file; testSpecs link matches testSpecs.md file |
| usm/gen-roadmap | mermaid-renders-in-vitepress | Mermaid code blocks render as diagrams, not raw text | — | Architecture page shows rendered diagram; Other mermaid blocks render properly |
| usm/gen-rules-files | all-tools-covered | All 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-files | two-tier-enforcement-parity | Iron 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/structurizr-bridge | import-never-destroys | Import 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-bridge | export-valid-dsl | Exported 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-bridge | target-registered | Export participates in the standard generate target system | — | structurizr accepted by --only; Output written under .usm-workspace/structurizr/ |
| usm/structurizr-bridge | conservative-mapping | Mapping 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-testspecs | test-specs-runnable | Generated 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-togaf | togaf-phase-coverage | Generator 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/agent-feedback | policy-respected | All 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-feedback | no-adhoc-tracking-files | The 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-feedback | feedback-schema-validated | Feedback entries are first-class .usm files validated against the schema | — | $type: feedback recognised by the v1 schema; Required fields: kind (bug |
| usm/agent-feedback | init-persists-policy | usm 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-feedback | smart-merge-preserved | Generator additions respect existing smart-merge guarantees | — | Feedback block rendered between USM markers only; Hand-written content outside markers unchanged |
| usm/mcp-contracts | contracts-feature-only | Contracts 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-flows | flows-feature-only | Flows tool only works on feature files | — | Returns error if file is not a feature; Each flow includes id, name, description, stepCount, steps |
| usm/mcp-list | list-returns-metadata | List 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-query | shared-evaluator | Query 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-query | read-only-capped | Read-only with context-safe capping | — | No file writes on any query path; Default limit 50 with total and truncated in the response |
| usm/mcp-read | read-returns-full-data | Read 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-references | references-deep-walk | References 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-search | search-top-10 | Search returns the top 10 most relevant results | — | Case-insensitive by default; Score based on occurrence count; Excerpt from summary around first match |
| usm/mcp-summary | summary-lightweight | Summary 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-validate | validate-inline-or-path | Validate 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-write | draft-validates-before-returning | draft_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-write | write-is-atomic | write_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-write | update-preserves-unspecified-fields | update_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-write | status-transitions-are-sane | update_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/schema-v1 | schema-three-types | The schema must support exactly three file types: system, service, feature | — | oneOf 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-v1 | schema-additional-properties-false | Each file type must set additionalProperties: false to prevent undocumented fields | — | systemFile.additionalProperties is false; serviceFile.additionalProperties is false; featureFile.additionalProperties is false |