modelgen-relational — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited modelgen-relational (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Extract structured module models from Agile user stories following a systematic DDD methodology.
Trigger this skill when the user asks to:
Before starting any work, resolve the application folder first (see Input Resolution below), then check CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md does not exist, skip this check (first-ever execution for this application).<app_folder>/CHANGELOG.md exists, scan all ## vX.Y.Z headings and determine the highest version using semantic versioning comparison."Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected." Do NOT proceed with any work.The skill requires mandatory <application> and <version> arguments, with an optional module: argument.
| Argument | Required | Description |
|---|---|---|
<application> | Yes | Application name — matched against root-level application folders |
<version> | Yes | Version label (e.g., v1.0.3). Used for version-filtered generation. |
module:<name> | No | Limit generation to a single module |
| Format | Example | Meaning |
|---|---|---|
| App + version | /modelgen-relational hub_middleware v1.0.3 | All modules, version-filtered |
| App + version + module | /modelgen-relational hub_middleware v1.0.3 module:Location Information | Single module, version-filtered |
| Module quoted | module:"Location Information" | Quoted form (equivalent) |
| Module snake_case | module:location_information | Converted to title-case for matching |
1_hub_middleware, 2_hc_adapter)<number>_ prefix from each folder name (e.g., 1_hub_middleware -> hub_middleware)snake_case, kebab-case, or title-case input (e.g., hub_middleware, hub-middleware, Hub Middleware all match 1_hub_middleware)| File | Resolved Path |
|---|---|
| PRD.md | <app_folder>/context/PRD.md |
| Output directory | <app_folder>/context/model/ |
snake_case input to title-case for matching (e.g., location_information -> Location Information)When a version argument is provided:
When combined with module:, both filters apply: only stories in the target module at or below the target version are processed.
This section defines the incremental update workflow for evolving an existing module model when user stories change across versions. Use this mode instead of full regeneration when working with a previously generated model.
Activate update mode when the user says:
The user must provide a new version identifier for the update (e.g., "1.1.0", "v2", "Sprint-4").
| Element | Description |
|---|---|
| Existing Model Directory | Path to previously generated output (must contain MODEL.md + module subdirectories with model.md and erd.mermaid) |
| Updated PRD.md | The updated user story file with changes (additions, modifications, removals) |
| New Version | Version label for this update (e.g., "1.1.0", "v2") |
#### Phase U1: Baseline Loading
#### Phase U2: Change Detection (Diff Analysis)
#### Phase U3: Staleness & Validity Check
For each existing model element (entity, attribute, relationship, enum value), check:
Produce a Staleness Report table:
| Element Type | Element Name | Module | Status | Reason | Affected Stories | Action |
|---|---|---|---|---|---|---|
| Entity | Order | Order Mgmt | ORPHANED | All source stories removed | [US-010] | REMOVE |
| Attribute | priority | Order | STALE | Source story US-005 modified | [US-005] | UPDATE |
Status values: ORPHANED, STALE, CONTRADICTED, VALID Action values: REMOVE, UPDATE, REVIEW, KEEP
#### Phase U4: Incremental Extraction
#### Phase U5: Model Merge
#### Phase U6: Output Regeneration
Before processing any input, read the full extraction methodology:
Read references/model-extraction-methodology.mdThis reference defines the 8-phase extraction pipeline in detail, including linguistic analysis heuristics, entity classification decision trees, attribute inference rules, relationship detection patterns, and NFR impact mappings. The instructions below orchestrate that methodology — always defer to the reference for phase-specific rules.
The user MUST provide the following structured input. If any required element is missing, ask the user to supply it before proceeding. Do NOT infer modules from story content.
| Element | Description |
|---|---|
| Module List | Explicit list of module names (bounded context candidates) |
| User Stories | Agile-format stories, each tagged with a module and a version. Format: "As [role], I want to [action] [object] so that [purpose]". The module associates the story to a bounded context. The version enables progressive model evolution tracking — every entity, attribute, relationship, and enum value in the output will reference the version that introduced it. |
| NFRs per Module | Non-functional requirements (security, performance, compliance, etc.) |
| Element | Description |
|---|---|
| Module Prefix Overrides | A 3-character prefix per module to override the auto-generated one. Format: Module Name: XXX. If not provided, the skill generates a prefix automatically (see Prefix Generation Rules). |
| Assumptions | Assumptions the user has made about the domain or requirements |
| Constraints | Technical or business constraints affecting the model |
| Glossary | Domain-specific term definitions (ubiquitous language) |
| Existing Data Model | Current-state model for migration or extension scenarios |
## Module: User Management
### Version: 1.0
- US-001: As an Admin, I want to create user accounts so that new employees can access the system.
- US-002: As an Admin, I want to assign roles to users so that access is controlled.
### Version: 1.1
- US-010: As an Admin, I want to deactivate user accounts so that former employees lose access.
- US-011: As a User, I want to update my profile so that my contact information stays current.
#### NFRs
- NFR-001: All entities must support soft delete.
- NFR-002: Audit trail required for all write operations.
#### Assumptions
- User accounts are internal only (no external/public registration).The version tag is freeform (e.g., 1.0, v2, Sprint-3, Phase-1). The skill does not enforce a versioning scheme but preserves the user's version labels exactly as provided.
Each module is assigned a 3-character uppercase prefix used in ERD entity names to support shared-database deployment. The prefix is auto-generated but can be overridden by the user.
Auto-generation algorithm (in order of preference):
USMORPINV (single word: first 3 characters)BILINVsuffix to the second one and truncate to 3 characters.
ORP, "Order Placement" → OPL (use first + second-word first two)OR1, OR2Rules:
USM_USER, ORP_ORDER).It does NOT appear in the model.md tables, where entities use their clean PascalCase names for readability.
erd.mermaid file as a commentand in a Module Prefix Map section in model.md.
Override: The user can supply prefix overrides in the input. Overrides must be exactly 3 uppercase characters and take priority over auto-generation.
[USHM00003], [NFRHM0003], [CONSHM003], [REFHM0003]). If ANY item is missing a tag, stop immediately and invoke the util-ustagger skill on the file to tag all untagged items. Only resume model extraction after all items are tagged. These tag codes will be used as the Source Story reference throughout the model output.<app_folder>/context/model/. Auto-create if the path doesn't exist (including any intermediate parent directories).Process ALL modules in a single pass. Each module is treated as an independent bounded context — do not model cross-module relationships. If you detect a potential cross-module dependency (e.g., Module A references an entity that looks like it belongs to Module B), note it in the assumptions table but do not create a relationship.
Within each module, process user stories in version order (earliest version first). Every model element — entity, attribute, relationship, enum value, domain event — must be annotated with the version that introduced it. This means:
Order first appears from stories in version 1.0, its version is 1.0.priority is added to Order by a story in version 1.1, thatattribute's version is 1.1, while the entity's version remains 1.0.
later version while existing values retain their original version.
This enables the user to trace exactly what changed at each version and supports progressive model growth across sprints or phases.
For each module, execute the following phases sequentially. The output is the final consolidated result — do NOT include intermediate phase analysis in the deliverables.
Parse each user story using the grammar-to-domain mapping from the methodology reference (Section 3). For compound stories with multiple verbs, decompose into individual operations.
Key extractions:
Classify every extracted noun using the decision flowchart from the methodology reference (Section 4.2):
Finite known set? → ENUM
Has identity + lifecycle? → Is it aggregate root? → AGGREGATE ROOT / ENTITY
Immutable, describes another? → VALUE OBJECT
Verb/action that happened? → DOMAIN EVENT
Otherwise → DOMAIN SERVICE or needs analysisApply naming conventions: PascalCase for entities, enums, events, value objects, join entities.
Derive attributes from four sources in priority order:
For each attribute, determine: name (camelCase), type, nullable, constraints, and source type (EXPLICIT, OPERATION_INFERENCE, NFR, CONVENTION, or ASSUMPTION).
#### Primary Key Convention
All entity primary keys MUST use UUID type with database-level generation. The UUID value MUST be generated by the database engine itself (e.g., gen_random_uuid() in PostgreSQL, UUID() in MySQL, NEWSEQUENTIALID() in SQL Server), NOT by the application layer. This is a mandatory convention for all entities including join entities.
Rationale: Application-generated UUIDs introduce performance overhead (extra network round-trips, inconsistent generation strategies across application instances, potential index fragmentation from random UUIDs). Database-generated UUIDs ensure consistent generation, reduce application complexity, and allow the database to use optimized UUID variants (e.g., UUIDv7 or sequential UUIDs) for better index performance.
In model documentation, annotate the id attribute with DB-generated UUID in the Constraints column to make this explicit.
When a story is ambiguous, propose defaults and record the ambiguity.
Detect relationships using the verb/preposition patterns from the methodology reference (Section 6.1). For each relationship, determine:
Promote M:N relationships to join entities with audit fields.
Scan NFRs and map each to model impact using the NFR-to-Model Impact Map (Appendix B of the methodology reference). Define a base entity specification if audit fields, soft delete, or optimistic locking are implied.
#### Phase 5a: Architecture Principle Integration
If PRD.md contains an # Architecture Principle section, read it and apply to model decisions:
If the # Architecture Principle section is absent, skip this sub-phase and proceed with existing behavior.
#### Phase 5b: Process Flow State Extraction
If PRD.md contains a # High Level Process Flow section, read it and extract state-related information:
If the # High Level Process Flow section is absent, skip this sub-phase.
Since modules are provided explicitly by the user, confirm each module as a bounded context. Within each context, identify aggregates by grouping entities with transactional cohesion. No aggregate should contain more than 4–5 entities.
Produce the two deliverables per module (see Output Specification below).
Run the completeness and quality checklists from the methodology reference (Section 10) as a self-review. Fix any issues found before presenting the output.
After all model files are successfully generated, append an entry to CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md. If it does not exist, create it with: # Changelog
- This file tracks all skill executions by version for this application.
- The highest version recorded here is the current application version.
- Skills MUST NOT execute for a version lower than the highest version in this file.
---## {version} heading matching the current version.--- below the context header and before any existing ## vX.Y.Z section (newest-first ordering), with a new table header and the first row.| {YYYY-MM-DD} | {application_name} | modelgen-relational | {module or "All"} | Generated relational module models |For each module, produce exactly two files plus one root-level summary file:
{module-dir}/erd.mermaidA valid Mermaid ER diagram file. Requirements:
erDiagram diagram type| Marker | Meaning | ||
|---|---|---|---|
| `\ | \ | ` | Exactly one |
| `o\ | ` | Zero or one | |
| `\ | {` | One or more | |
o{ | Zero or more |
USM_USER, USM_ROLE)cumulative model across all versions. Per-element version tracking is captured in the companion model.md file. Add a Mermaid comment at the top of the file listing the versions included and the module prefix mapping.
Example structure:
%% Module: User Management | Prefix: USM
%% Versions included: 1.0, 1.1
erDiagram
USM_USER {
uuid id PK
string username
string email
string status
timestamp created_at
string created_by
timestamp updated_at
string updated_by
}
USM_ROLE {
uuid id PK
string name
string description
}
USM_USER_ROLE {
uuid id PK
uuid user_id FK
uuid role_id FK
timestamp assigned_at
string assigned_by
}
USM_USER ||--o{ USM_USER_ROLE : "has"
USM_ROLE ||--o{ USM_USER_ROLE : "assigned to"{domain-dir}/model.mdA markdown file containing the following sections. Use tables for all structured data.
#### Document Structure
# Module Model: {Module Name}
## 1. Module Prefix Map
| Module | Prefix | Auto-Generated | Override |
|--------|--------|----------------|----------|
(e.g., User Management | USM | Yes | — )
## 2. Entity Catalog
| Entity | DDD Type | Bounded Context | Key Attributes | Relationships | Source Stories | Version |
|--------|----------|-----------------|----------------|---------------|---------------|---------|
## 3. Base Entity Specification
(If applicable — audit fields, soft delete, versioning inherited by all entities)
## 4. Attribute Detail
(One subsection per entity with full attribute table)
### 4.x {Entity Name}
| Attribute | Type | Nullable | Constraints | Source | Source Story | Version |
|-----------|------|----------|-------------|--------|--------------|---------|
## 5. Relationship Catalog
| Source Entity | Target Entity | Cardinality | Join Entity | Cascade | Business Rule | Source Story | Version |
|---------------|---------------|-------------|-------------|---------|---------------|-------------|---------|
## 6. Enum Definitions
(One subsection per enum)
### 6.x {Enum Name}
| Value | Description | Source Story | Version |
|-------|-------------|--------------|---------|
## 7. Domain Events
| Event Name | Trigger Story | Aggregate | Payload Fields | Version |
|------------|---------------|-----------|----------------|---------|
## 8. Bounded Context Summary
| Context | Aggregates | Description |
|---------|------------|-------------|
## 9. Assumptions and Ambiguities
| Story ID | Entity / Attribute | Assumption Made | Clarification Needed | Version |
|----------|--------------------|-----------------|----------------------|---------|
## 10. Changelog
### Version {new-version} (from {previous-version})
#### Added
| Element Type | Name | Description | Source Stories |
|---|---|---|---|
#### Modified
| Element Type | Name | Change Description | Previous | New | Source Stories |
|---|---|---|---|---|---|
#### Removed
| Element Type | Name | Reason | Former Source Stories |
|---|---|---|---|
#### Flagged for Review
| Element Type | Name | Issue | Recommendation |
|---|---|---|---|MODEL.mdAfter generating all per-module files, produce a single MODEL.md in the root output directory. This file serves as the entry point and table of contents for the entire model extraction output.
#### Document Structure
# Module Model Summary
> Generated from {total story count} user stories across {module count} modules.
## Modules
| # | Module | Prefix | Entities | Relationships | Versions | Stories |
|---|--------|--------|----------|---------------|----------|---------|
(One row per module. Entities = count of entities in that module. Relationships = count of
relationships. Versions = comma-separated list of versions included. Stories = count of
source stories for that module.)
## Table of Contents
### {Module Name} (`{prefix}`)
> {One-line summary: e.g., "Manages user accounts, roles, and permissions."}
- **Model Documentation:** [{module-kebab}/model.md](./{module-kebab}/model.md)
- **ERD Diagram:** [{module-kebab}/erd.mermaid](./{module-kebab}/erd.mermaid)
- **Entities:** {comma-separated PascalCase entity names}
- **Key Relationships:** {2–3 most significant relationships in natural language}
(Repeat for each module, in the same order as the Modules table.)
## Cross-Module Dependencies
| Source Module | Target Module | Dependency | Noted In |
|---------------|---------------|------------|----------|
(List any cross-module dependencies flagged in assumptions tables. If none, state "No
cross-module dependencies were identified.")
## Assumptions Summary
| Module | Count | Critical |
|--------|-------|----------|
(Count = total assumptions for that module. Critical = count of assumptions marked as
needing clarification. Links to the respective module's Assumptions and Ambiguities section.)
## Update History
| Version | Date | Modules Affected | Added | Modified | Removed | Flagged |
|---|---|---|---|---|---|---|Module-to-story mapping must be provided by the user.
modules. Flag potential cross-module dependencies in the assumptions table.
intermediate linguistic analysis, noun classification lists, or phase-by-phase working notes in the deliverables.
reference its originating user story ID or NFR.
Assumptions and Ambiguities table with a clarification question.
All output files are written under the user-specified output directory, organized as one subdirectory per module. Module names are converted to kebab-case for directory names.
Given an output directory /path/to/output and three modules — "User Management", "Order Management", and "Inventory":
/path/to/output/
├── MODEL.md # Root summary and table of contents
├── user-management/
│ ├── erd.mermaid
│ └── model.md
├── order-management/
│ ├── erd.mermaid
│ └── model.md
└── inventory/
├── erd.mermaid
└── model.mdThe root directory contains:
MODEL.md — summary and table of contents linking to all module modelsEach subdirectory contains exactly two files:
erd.mermaid — the Mermaid ERD diagram for that modulemodel.md — the full model documentation for that moduleBefore presenting output, verify:
id field (UUID, DB-generated) and audit fields (or inherits from base entity)MODEL.md is generated with correct links to all module subdirectoriesMODEL.md module statistics (entity count, relationship count, story count) match actual outputWhen running in update mode, additionally verify:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.