ALPS Profile Assistant
Generate, validate, and improve ALPS profiles for RESTful API design.
Ideal ALPS Profile
Goal: An ALPS that someone unfamiliar with the app can read and understand.
What Makes a Good ALPS
States = What the user sees
ProductList - viewing a list of products
ProductDetail - viewing one product
Cart - viewing cart contents
Transitions = What the user does
goProductDetail - select a product
doAddToCart - add to cart
Self-documenting
title explains the purpose
doc describes behavior and side effects
- No need to read code to understand
No unreachable states
- Every state has an entry point
- Orphan states indicate design mistakes
Necessary and sufficient
- No over-abstraction
- Describes semantics, not implementation
- No HTTP methods or URLs
What to Avoid
- Mechanical CRUD listings without meaning
- Implementation details leaking in
- States without transitions (can't draw a diagram)
- Excessive documentation nobody reads
How to Use
This skill responds to natural language requests:
Generate ALPS from Natural Language
- "Create an ALPS profile for a blog application"
- "Generate ALPS for an e-commerce cart system"
- "Design an ALPS profile for user authentication"
Validate Existing Profile
- "Validate this ALPS profile" (with file path or content)
- "Check my ALPS file for issues"
- "Review the ALPS profile at docs/api.json"
Get Improvement Suggestions
- "Improve this ALPS profile"
- "Suggest enhancements for my ALPS"
- "How can I make this ALPS better?"
ALPS Structure Reference
Three Layers of ALPS
Ontology - Semantic descriptors (data elements)
- Atomic data fields with
type="semantic" (default)
- Should have
id, title, and optionally doc and def (schema.org link)
Taxonomy - State descriptors (screens/pages)
- Composite descriptors containing semantic fields and transitions
- Represents application states (e.g., HomePage, ProductDetail, Cart)
Choreography - Transition descriptors (actions)
type="safe" - Read operations (GET)
type="unsafe" - Create operations (POST) - not idempotent
type="idempotent" - Update/Delete operations (PUT/DELETE)
- Must have
rt (return type) pointing to target state
Naming Conventions
| Type |
Prefix |
Example |
| Safe transition |
go |
goToHome, goProductList, goSearchProducts |
| Unsafe transition |
do |
doCreateUser, doAddToCart, doLogin |
| Idempotent transition |
do |
doUpdateUser, doDeleteItem, doRemoveFromCart |
| State/Page |
PascalCase |
HomePage, ProductDetail, ShoppingCart |
| Semantic field |
camelCase |
userId, productName, createdAt |
Safe Transition Naming Rule
IMPORTANT: Safe transitions (go*) MUST include the target state name in their id.
rt="#ProductList" → id must be goProductList (or goToProductList)
rt="#UserProfile" → id must be goUserProfile (or goToUserProfile)
Invalid examples:
goStart with rt="#ProductList" - Wrong! Should be goProductList
goNext with rt="#Checkout" - Wrong! Should be goCheckout
This rule ensures consistency and makes the diagram self-documenting. When a transition has no source state (entry point), it will be displayed as originating from UnknownState in the diagram.
Determining idempotent: PUT vs DELETE
Context clues for AI inference:
PUT (Update) indicators:
update, edit, modify, change, set, replace
- Example:
doUpdateProfile, doEditComment, doSetQuantity
DELETE indicators:
delete, remove, cancel, clear, destroy
- Example:
doDeleteUser, doRemoveFromCart, doCancelOrder
Generation Guidelines
When Creating ALPS from Natural Language
IMPORTANT: Structure the ALPS file in three blocks in this order:
Identify Entities (Ontology - Semantic definitions)
- Extract nouns: user, product, order, cart, etc.
- Define atomic fields for each entity
- Add
def links to schema.org where applicable
- Add
doc for validation rules, formats, constraints
Identify States (Taxonomy - Inclusion relationships)
- Map user journey: login -> home -> browse -> cart -> checkout
- Each state contains relevant fields and available transitions
- Use PascalCase for state names
- Add
doc explaining what user sees and available actions
Identify Transitions (Choreography - State transitions)
- Safe: navigation, viewing, searching (prefix:
go)
- Unsafe: creating new resources (prefix:
do)
- Idempotent: updating or deleting resources (prefix:
do)
- Add
doc explaining behavior, side effects, preconditions
Add Documentation
- Every descriptor MUST have a meaningful
title
- Add
doc when title alone cannot fully explain the descriptor:
- Semantic fields: Validation rules, format requirements, constraints, examples
- Example:
{"id": "title", "title": "Title", "doc": {"value": "Article title. Maximum 100 characters."}}
- States: What user sees, available actions, when this state is shown
- Example:
{"id": "BlogPost", "doc": {"value": "User-created article. Visible to all users after publication."}}
- Transitions: Behavior, side effects, preconditions, error cases
- Example:
{"id": "doPublishBlogPost", "doc": {"value": "Publish article. Sets publishedAt to current time."}}
- Use
def to link to schema.org definitions for standard concepts
- Rule of thumb: If someone unfamiliar with the app would ask "what does this do?" or "what format?", add
doc
Add Tags for Organization
- Functional area tags: Group by feature domain (e.g.,
search, product, cart, checkout, order, account, review)
- Flow tags: Group by user journey with
flow- prefix (e.g., flow-purchase, flow-register, flow-return)
- States and transitions should have both types where applicable
- Tags are space-separated strings, not arrays
- Example: A cart-related transition might have
"tag": "cart flow-purchase"
Add Semantic Descriptors to Transitions
- Every transition (go/do) should specify its required input parameters as nested descriptors
- These define what data is needed to perform the action
- Example:
{"id": "goProductDetail", "type": "safe", "rt": "#ProductDetail", "tag": "product", "descriptor": [
{"href": "#productId"}
]},
{"id": "doAddToCart", "type": "unsafe", "rt": "#Cart", "tag": "cart flow-purchase", "descriptor": [
{"href": "#productId"},
{"href": "#quantity"},
{"href": "#selectedVariant"}
]}
MANDATORY: Validate After Generation
- After generating ALPS JSON, save it to a temporary file
- Run
asd --validate <file> to validate (outputs JSON per validation-result.json schema)
- Parse the JSON result and report issues to the user
- If errors exist, fix them before presenting the final output
Output Format
Generate XML format by default. Use JSON only if explicitly requested.
XML Format (default):
- Use XML comments to mark blocks:
<!-- Ontology -->, <!-- Taxonomy -->, <!-- Choreography -->
- One descriptor per line for simple elements
- Multi-line for nested structures
- Clear hierarchical structure makes maintenance easy
<?xml version="1.0" encoding="UTF-8"?>
<alps version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://alps-io.github.io/schemas/alps.xsd">
<title>Application Title</title>
<doc>Description of the application</doc>
<!-- Ontology -->
<descriptor id="fieldName" title="Human Title">
<doc>Description</doc>
</descriptor>
<descriptor id="otherField" title="Other Field"/>
<!-- Taxonomy -->
<descriptor id="StateName" title="State Title">
<descriptor href="#fieldName"/>
<descriptor href="#transitionName"/>
</descriptor>
<!-- Choreography -->
<descriptor id="goTargetState" type="safe" rt="#TargetState" title="Go to Target State"/>
<descriptor id="doAction" type="unsafe" rt="#ResultState" title="Perform Action">
<descriptor href="#requiredField"/>
</descriptor>
</alps>
JSON Format (when explicitly requested):
- Simple descriptors (few attributes, no nesting): Write on a single line
- Complex descriptors (with nesting or long
doc): Use multiple lines with "descriptor": [ at end of first line
- Block separation: Add ONE blank line between Ontology/Taxonomy/Choreography blocks
- No other blank lines: Keep descriptors within the same block compact
{
"$schema": "https://alps-io.github.io/schemas/alps.json",
"alps": {
"title": "Application Title",
"doc": {"value": "Description of the application"},
"descriptor": [
{"id": "fieldName", "title": "Human Title", "doc": {"value": "Description"}},
{"id": "otherField", "title": "Other Field"},
{"id": "StateName", "title": "State Title", "descriptor": [
{"href": "#fieldName"},
{"href": "#transitionName"}
]},
{"id": "goTargetState", "type": "safe", "rt": "#TargetState", "title": "Go to Target State"},
{"id": "doAction", "type": "unsafe", "rt": "#ResultState", "title": "Perform Action", "descriptor": [
{"href": "#requiredField"}
]}
]
}
}
Validation
Use asd --validate <file> to validate ALPS profiles. Output conforms to the validation-result.json schema.
Error Codes (E)
- E001: Missing id or href
- E002: Missing rt on transition
- E003: Invalid type
- E004: Broken reference
- E005: Duplicate id
- E006: Invalid href
- E007: Invalid rt format
- E008: Missing alps property in document
- E009: Descriptor must be an array
- E010: Invalid XML character in descriptor title
- E011: Tag must be a string (space-separated), not an array
Warning Codes (W)
- W001: Missing title
- W002: Safe transition naming (should start with 'go')
- W003: Unsafe/idempotent naming (should start with 'do')
- W004: Orphan descriptor
- W005: Safe transition id does not match rt target (e.g.,
goStart with rt="#ProductList" should be goProductList)
- W006: Tag contains comma - may be confused with space-separated format
Suggestion Codes (S)
- S001: Missing doc on transition
- S002: Missing ALPS title
- S003: Missing ALPS doc
Example: Blog Application
Input: "Create an ALPS for a simple blog with posts and comments"
Output (XML - default):
<?xml version="1.0" encoding="UTF-8"?>
<alps version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://alps-io.github.io/schemas/alps.xsd">
<title>Simple Blog</title>
<doc>ALPS profile for a blog application with posts and comments</doc>
<!-- Ontology -->
<descriptor id="postId" title="Post ID" def="https://schema.org/identifier">
<doc>Unique identifier for blog post</doc>
</descriptor>
<descriptor id="title" title="Post Title" def="https://schema.org/headline">
<doc>Article title. Maximum 100 characters.</doc>
</descriptor>
<descriptor id="body" title="Post Body" def="https://schema.org/articleBody">
<doc>Article content. Markdown format supported.</doc>
</descriptor>
<descriptor id="authorName" title="Author Name" def="https://schema.org/author"/>
<descriptor id="createdAt" title="Created Date" def="https://schema.org/dateCreated">
<doc>Publication date and time. ISO 8601 format.</doc>
</descriptor>
<descriptor id="commentId" title="Comment ID">
<doc>Unique identifier for comment</doc>
</descriptor>
<descriptor id="commentBody" title="Comment Text">
<doc>Comment content. Maximum 500 characters.</doc>
</descriptor>
<!-- Taxonomy -->
<descriptor id="Home" title="Home Page">
<doc>Blog home page. Shows navigation to post list.</doc>
<descriptor href="#goPostList"/>
</descriptor>
<descriptor id="PostList" title="Post List">
<doc>List of blog posts. Shows latest 10 posts with title and author.</doc>
<descriptor href="#postId"/>
<descriptor href="#title"/>
<descriptor href="#authorName"/>
<descriptor href="#goPostDetail"/>
<descriptor href="#goHome"/>
</descriptor>
<descriptor id="PostDetail" title="Post Detail">
<doc>Single post view. Shows full content and comments. Allows adding new comments.</doc>
<descriptor href="#postId"/>
<descriptor href="#title"/>
<descriptor href="#body"/>
<descriptor href="#authorName"/>
<descriptor href="#createdAt"/>
<descriptor href="#Comment"/>
<descriptor href="#goPostList"/>
<descriptor href="#doCreateComment"/>
</descriptor>
<descriptor id="Comment" title="Comment">
<doc>User comment on a post. Can be deleted by comment author or post author.</doc>
<descriptor href="#commentId"/>
<descriptor href="#commentBody"/>
<descriptor href="#authorName"/>
<descriptor href="#createdAt"/>
<descriptor href="#doDeleteComment"/>
</descriptor>
<!-- Choreography -->
<descriptor id="goHome" type="safe" rt="#Home" title="Go to Home">
<doc>Navigate to blog home page.</doc>
</descriptor>
<descriptor id="goPostList" type="safe" rt="#PostList" title="Go to Post List">
<doc>Display list of blog posts. Shows latest 10 posts.</doc>
</descriptor>
<descriptor id="goPostDetail" type="safe" rt="#PostDetail" title="Go to Post Detail">
<doc>Display full post content with comments.</doc>
<descriptor href="#postId"/>
</descriptor>
<descriptor id="doCreatePost" type="unsafe" rt="#PostDetail" title="Create Post">
<doc>Create new blog post. Post is immediately published.</doc>
<descriptor href="#title"/>
<descriptor href="#body"/>
</descriptor>
<descriptor id="doUpdatePost" type="idempotent" rt="#PostDetail" title="Update Post">
<doc>Update existing post content. Only post author can update.</doc>
<descriptor href="#postId"/>
<descriptor href="#title"/>
<descriptor href="#body"/>
</descriptor>
<descriptor id="doDeletePost" type="idempotent" rt="#PostList" title="Delete Post">
<doc>Delete post and all associated comments. Only post author can delete.</doc>
<descriptor href="#postId"/>
</descriptor>
<descriptor id="doCreateComment" type="unsafe" rt="#PostDetail" title="Add Comment">
<doc>Add comment to post. Comment is immediately visible.</doc>
<descriptor href="#postId"/>
<descriptor href="#commentBody"/>
</descriptor>
<descriptor id="doDeleteComment" type="idempotent" rt="#PostDetail" title="Delete Comment">
<doc>Delete comment. Comment author or post author can delete.</doc>
<descriptor href="#commentId"/>
</descriptor>
</alps>
Integration with app-state-diagram
Generated ALPS profiles can be visualized using app-state-diagram:
# Generate HTML diagram
asd profile.json
# Generate with watch mode
asd --watch profile.json
# Generate markdown documentation
asd --mode=markdown profile.json
Advanced Features
Structured Documentation with HTML
For simple descriptions, use plain text in doc.value. When you need structured content (lists, definitions, tables), use HTML format:
{"id": "doCheckout", "type": "unsafe", "rt": "#OrderConfirmation",
"title": "Complete Checkout",
"doc": {
"format": "html",
"value": "<dl><dt>Behavior</dt><dd>Processes payment, reserves inventory, sends confirmation email</dd><dt>Preconditions</dt><dd>Valid cart with items, payment method configured</dd><dt>Errors</dt><dd>Returns 400 if payment fails or items out of stock</dd></dl>"
}
}
Format support levels (per ALPS spec):
text: Required (default if not specified)
html: Recommended
markdown: Optional
asciidoc: Optional
Links to Related Resources
Use link elements to reference external documentation, schemas, or related resources:
{"id": "BlogPost", "def": "https://schema.org/BlogPosting",
"title": "Blog Post",
"doc": {"value": "User-created article visible to all after publication"},
"link": [
{"rel": "help", "href": "https://example.com/docs/blog-api.html", "title": "Blog API Documentation"},
{"rel": "related", "href": "https://example.com/schemas/post.json", "title": "JSON Schema"}
]
}
Link attributes:
rel (required): Relationship type - use IANA Link Relations (help, related, profile, etc.)
href (required): URL to the related resource
title (optional): Human-readable description of the link
tag (optional): Classification tags
Tips for Better ALPS
- Start with user journeys - Map the happy path first, then add alternatives
- Be consistent - Use the same naming pattern throughout
- Document transitions - Explain what each action does and when it's available
- Use schema.org - Link to standard definitions for interoperability
- Think about errors - Add error states and recovery transitions
- Consider pagination - List states should support pagination
- Tag descriptors - Use
tag attribute to group related descriptors
References
1---2name: alps3description: Create, validate, and improve ALPS profiles for RESTful API design, generating from natural language and providing validation and improvement suggestions.4---56# ALPS Profile Assistant78Generate, validate, and improve ALPS profiles for RESTful API design.910## Ideal ALPS Profile1112**Goal: An ALPS that someone unfamiliar with the app can read and understand.**1314### What Makes a Good ALPS15161. **States = What the user sees**17 - `ProductList` - viewing a list of products18 - `ProductDetail` - viewing one product19 - `Cart` - viewing cart contents20212. **Transitions = What the user does**22 - `goProductDetail` - select a product23 - `doAddToCart` - add to cart24253. **Self-documenting**26 - `title` explains the purpose27 - `doc` describes behavior and side effects28 - No need to read code to understand29304. **No unreachable states**31 - Every state has an entry point32 - Orphan states indicate design mistakes33345. **Necessary and sufficient**35 - No over-abstraction36 - Describes semantics, not implementation37 - No HTTP methods or URLs3839### What to Avoid4041- Mechanical CRUD listings without meaning42- Implementation details leaking in43- States without transitions (can't draw a diagram)44- Excessive documentation nobody reads4546## How to Use4748This skill responds to natural language requests:4950### Generate ALPS from Natural Language51- "Create an ALPS profile for a blog application"52- "Generate ALPS for an e-commerce cart system"53- "Design an ALPS profile for user authentication"5455### Validate Existing Profile56- "Validate this ALPS profile" (with file path or content)57- "Check my ALPS file for issues"58- "Review the ALPS profile at docs/api.json"5960### Get Improvement Suggestions61- "Improve this ALPS profile"62- "Suggest enhancements for my ALPS"63- "How can I make this ALPS better?"6465## ALPS Structure Reference6667### Three Layers of ALPS68691. **Ontology** - Semantic descriptors (data elements)70 - Atomic data fields with `type="semantic"` (default)71 - Should have `id`, `title`, and optionally `doc` and `def` (schema.org link)72732. **Taxonomy** - State descriptors (screens/pages)74 - Composite descriptors containing semantic fields and transitions75 - Represents application states (e.g., HomePage, ProductDetail, Cart)76773. **Choreography** - Transition descriptors (actions)78 - `type="safe"` - Read operations (GET)79 - `type="unsafe"` - Create operations (POST) - not idempotent80 - `type="idempotent"` - Update/Delete operations (PUT/DELETE)81 - Must have `rt` (return type) pointing to target state8283### Naming Conventions8485| Type | Prefix | Example |86|------|--------|---------|87| Safe transition | `go` | `goToHome`, `goProductList`, `goSearchProducts` |88| Unsafe transition | `do` | `doCreateUser`, `doAddToCart`, `doLogin` |89| Idempotent transition | `do` | `doUpdateUser`, `doDeleteItem`, `doRemoveFromCart` |90| State/Page | PascalCase | `HomePage`, `ProductDetail`, `ShoppingCart` |91| Semantic field | camelCase | `userId`, `productName`, `createdAt` |9293### Safe Transition Naming Rule9495**IMPORTANT**: Safe transitions (`go*`) MUST include the target state name in their id.9697- `rt="#ProductList"` → id must be `goProductList` (or `goToProductList`)98- `rt="#UserProfile"` → id must be `goUserProfile` (or `goToUserProfile`)99100**Invalid examples:**101- `goStart` with `rt="#ProductList"` - Wrong! Should be `goProductList`102- `goNext` with `rt="#Checkout"` - Wrong! Should be `goCheckout`103104This rule ensures consistency and makes the diagram self-documenting. When a transition has no source state (entry point), it will be displayed as originating from `UnknownState` in the diagram.105106### Determining idempotent: PUT vs DELETE107108Context clues for AI inference:109110**PUT (Update) indicators:**111- `update`, `edit`, `modify`, `change`, `set`, `replace`112- Example: `doUpdateProfile`, `doEditComment`, `doSetQuantity`113114**DELETE indicators:**115- `delete`, `remove`, `cancel`, `clear`, `destroy`116- Example: `doDeleteUser`, `doRemoveFromCart`, `doCancelOrder`117118## Generation Guidelines119120### When Creating ALPS from Natural Language121122**IMPORTANT**: Structure the ALPS file in three blocks in this order:1231241. **Identify Entities** (Ontology - Semantic definitions)125 - Extract nouns: user, product, order, cart, etc.126 - Define atomic fields for each entity127 - Add `def` links to schema.org where applicable128 - Add `doc` for validation rules, formats, constraints1291302. **Identify States** (Taxonomy - Inclusion relationships)131 - Map user journey: login -> home -> browse -> cart -> checkout132 - Each state contains relevant fields and available transitions133 - Use PascalCase for state names134 - Add `doc` explaining what user sees and available actions1351363. **Identify Transitions** (Choreography - State transitions)137 - Safe: navigation, viewing, searching (prefix: `go`)138 - Unsafe: creating new resources (prefix: `do`)139 - Idempotent: updating or deleting resources (prefix: `do`)140 - Add `doc` explaining behavior, side effects, preconditions1411424. **Add Documentation**143 - Every descriptor MUST have a meaningful `title`144 - Add `doc` when title alone cannot fully explain the descriptor:145 - **Semantic fields**: Validation rules, format requirements, constraints, examples146 - Example: `{"id": "title", "title": "Title", "doc": {"value": "Article title. Maximum 100 characters."}}`147 - **States**: What user sees, available actions, when this state is shown148 - Example: `{"id": "BlogPost", "doc": {"value": "User-created article. Visible to all users after publication."}}`149 - **Transitions**: Behavior, side effects, preconditions, error cases150 - Example: `{"id": "doPublishBlogPost", "doc": {"value": "Publish article. Sets publishedAt to current time."}}`151 - Use `def` to link to schema.org definitions for standard concepts152 - **Rule of thumb**: If someone unfamiliar with the app would ask "what does this do?" or "what format?", add `doc`1531545. **Add Tags for Organization**155 - **Functional area tags**: Group by feature domain (e.g., `search`, `product`, `cart`, `checkout`, `order`, `account`, `review`)156 - **Flow tags**: Group by user journey with `flow-` prefix (e.g., `flow-purchase`, `flow-register`, `flow-return`)157 - States and transitions should have both types where applicable158 - Tags are space-separated strings, not arrays159 - Example: A cart-related transition might have `"tag": "cart flow-purchase"`1601616. **Add Semantic Descriptors to Transitions**162 - Every transition (go/do) should specify its required input parameters as nested descriptors163 - These define what data is needed to perform the action164 - Example:165 ```json166 {"id": "goProductDetail", "type": "safe", "rt": "#ProductDetail", "tag": "product", "descriptor": [167 {"href": "#productId"}168 ]},169 {"id": "doAddToCart", "type": "unsafe", "rt": "#Cart", "tag": "cart flow-purchase", "descriptor": [170 {"href": "#productId"},171 {"href": "#quantity"},172 {"href": "#selectedVariant"}173 ]}174 ```1751767. **MANDATORY: Validate After Generation**177 - After generating ALPS JSON, save it to a temporary file178 - Run `asd --validate <file>` to validate (outputs JSON per validation-result.json schema)179 - Parse the JSON result and report issues to the user180 - If errors exist, fix them before presenting the final output181182### Output Format183184Generate XML format by default. Use JSON only if explicitly requested.185186**XML Format** (default):187- Use XML comments to mark blocks: `<!-- Ontology -->`, `<!-- Taxonomy -->`, `<!-- Choreography -->`188- One descriptor per line for simple elements189- Multi-line for nested structures190- Clear hierarchical structure makes maintenance easy191192```xml193<?xml version="1.0" encoding="UTF-8"?>194<alps version="1.0"195 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"196 xsi:noNamespaceSchemaLocation="https://alps-io.github.io/schemas/alps.xsd">197 <title>Application Title</title>198 <doc>Description of the application</doc>199200 <!-- Ontology -->201 <descriptor id="fieldName" title="Human Title">202 <doc>Description</doc>203 </descriptor>204 <descriptor id="otherField" title="Other Field"/>205206 <!-- Taxonomy -->207 <descriptor id="StateName" title="State Title">208 <descriptor href="#fieldName"/>209 <descriptor href="#transitionName"/>210 </descriptor>211212 <!-- Choreography -->213 <descriptor id="goTargetState" type="safe" rt="#TargetState" title="Go to Target State"/>214 <descriptor id="doAction" type="unsafe" rt="#ResultState" title="Perform Action">215 <descriptor href="#requiredField"/>216 </descriptor>217</alps>218```219220**JSON Format** (when explicitly requested):221- **Simple descriptors** (few attributes, no nesting): Write on a single line222- **Complex descriptors** (with nesting or long `doc`): Use multiple lines with `"descriptor": [` at end of first line223- **Block separation**: Add ONE blank line between Ontology/Taxonomy/Choreography blocks224- **No other blank lines**: Keep descriptors within the same block compact225226```json227{228 "$schema": "https://alps-io.github.io/schemas/alps.json",229 "alps": {230 "title": "Application Title",231 "doc": {"value": "Description of the application"},232 "descriptor": [233 {"id": "fieldName", "title": "Human Title", "doc": {"value": "Description"}},234 {"id": "otherField", "title": "Other Field"},235236 {"id": "StateName", "title": "State Title", "descriptor": [237 {"href": "#fieldName"},238 {"href": "#transitionName"}239 ]},240241 {"id": "goTargetState", "type": "safe", "rt": "#TargetState", "title": "Go to Target State"},242 {"id": "doAction", "type": "unsafe", "rt": "#ResultState", "title": "Perform Action", "descriptor": [243 {"href": "#requiredField"}244 ]}245 ]246 }247}248```249250## Validation251252Use `asd --validate <file>` to validate ALPS profiles. Output conforms to the [validation-result.json schema](https://alps-asd.github.io/app-state-diagram/schemas/validation-result.json).253254### Error Codes (E)255- E001: Missing id or href256- E002: Missing rt on transition257- E003: Invalid type258- E004: Broken reference259- E005: Duplicate id260- E006: Invalid href261- E007: Invalid rt format262- E008: Missing alps property in document263- E009: Descriptor must be an array264- E010: Invalid XML character in descriptor title265- E011: Tag must be a string (space-separated), not an array266267### Warning Codes (W)268- W001: Missing title269- W002: Safe transition naming (should start with 'go')270- W003: Unsafe/idempotent naming (should start with 'do')271- W004: Orphan descriptor272- W005: Safe transition id does not match rt target (e.g., `goStart` with `rt="#ProductList"` should be `goProductList`)273- W006: Tag contains comma - may be confused with space-separated format274275### Suggestion Codes (S)276- S001: Missing doc on transition277- S002: Missing ALPS title278- S003: Missing ALPS doc279280## Example: Blog Application281282Input: "Create an ALPS for a simple blog with posts and comments"283284Output (XML - default):285```xml286<?xml version="1.0" encoding="UTF-8"?>287<alps version="1.0"288 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"289 xsi:noNamespaceSchemaLocation="https://alps-io.github.io/schemas/alps.xsd">290 <title>Simple Blog</title>291 <doc>ALPS profile for a blog application with posts and comments</doc>292293 <!-- Ontology -->294 <descriptor id="postId" title="Post ID" def="https://schema.org/identifier">295 <doc>Unique identifier for blog post</doc>296 </descriptor>297 <descriptor id="title" title="Post Title" def="https://schema.org/headline">298 <doc>Article title. Maximum 100 characters.</doc>299 </descriptor>300 <descriptor id="body" title="Post Body" def="https://schema.org/articleBody">301 <doc>Article content. Markdown format supported.</doc>302 </descriptor>303 <descriptor id="authorName" title="Author Name" def="https://schema.org/author"/>304 <descriptor id="createdAt" title="Created Date" def="https://schema.org/dateCreated">305 <doc>Publication date and time. ISO 8601 format.</doc>306 </descriptor>307 <descriptor id="commentId" title="Comment ID">308 <doc>Unique identifier for comment</doc>309 </descriptor>310 <descriptor id="commentBody" title="Comment Text">311 <doc>Comment content. Maximum 500 characters.</doc>312 </descriptor>313314 <!-- Taxonomy -->315 <descriptor id="Home" title="Home Page">316 <doc>Blog home page. Shows navigation to post list.</doc>317 <descriptor href="#goPostList"/>318 </descriptor>319 <descriptor id="PostList" title="Post List">320 <doc>List of blog posts. Shows latest 10 posts with title and author.</doc>321 <descriptor href="#postId"/>322 <descriptor href="#title"/>323 <descriptor href="#authorName"/>324 <descriptor href="#goPostDetail"/>325 <descriptor href="#goHome"/>326 </descriptor>327 <descriptor id="PostDetail" title="Post Detail">328 <doc>Single post view. Shows full content and comments. Allows adding new comments.</doc>329 <descriptor href="#postId"/>330 <descriptor href="#title"/>331 <descriptor href="#body"/>332 <descriptor href="#authorName"/>333 <descriptor href="#createdAt"/>334 <descriptor href="#Comment"/>335 <descriptor href="#goPostList"/>336 <descriptor href="#doCreateComment"/>337 </descriptor>338 <descriptor id="Comment" title="Comment">339 <doc>User comment on a post. Can be deleted by comment author or post author.</doc>340 <descriptor href="#commentId"/>341 <descriptor href="#commentBody"/>342 <descriptor href="#authorName"/>343 <descriptor href="#createdAt"/>344 <descriptor href="#doDeleteComment"/>345 </descriptor>346347 <!-- Choreography -->348 <descriptor id="goHome" type="safe" rt="#Home" title="Go to Home">349 <doc>Navigate to blog home page.</doc>350 </descriptor>351 <descriptor id="goPostList" type="safe" rt="#PostList" title="Go to Post List">352 <doc>Display list of blog posts. Shows latest 10 posts.</doc>353 </descriptor>354 <descriptor id="goPostDetail" type="safe" rt="#PostDetail" title="Go to Post Detail">355 <doc>Display full post content with comments.</doc>356 <descriptor href="#postId"/>357 </descriptor>358 <descriptor id="doCreatePost" type="unsafe" rt="#PostDetail" title="Create Post">359 <doc>Create new blog post. Post is immediately published.</doc>360 <descriptor href="#title"/>361 <descriptor href="#body"/>362 </descriptor>363 <descriptor id="doUpdatePost" type="idempotent" rt="#PostDetail" title="Update Post">364 <doc>Update existing post content. Only post author can update.</doc>365 <descriptor href="#postId"/>366 <descriptor href="#title"/>367 <descriptor href="#body"/>368 </descriptor>369 <descriptor id="doDeletePost" type="idempotent" rt="#PostList" title="Delete Post">370 <doc>Delete post and all associated comments. Only post author can delete.</doc>371 <descriptor href="#postId"/>372 </descriptor>373 <descriptor id="doCreateComment" type="unsafe" rt="#PostDetail" title="Add Comment">374 <doc>Add comment to post. Comment is immediately visible.</doc>375 <descriptor href="#postId"/>376 <descriptor href="#commentBody"/>377 </descriptor>378 <descriptor id="doDeleteComment" type="idempotent" rt="#PostDetail" title="Delete Comment">379 <doc>Delete comment. Comment author or post author can delete.</doc>380 <descriptor href="#commentId"/>381 </descriptor>382</alps>383```384385## Integration with app-state-diagram386387Generated ALPS profiles can be visualized using app-state-diagram:388389```bash390# Generate HTML diagram391asd profile.json392393# Generate with watch mode394asd --watch profile.json395396# Generate markdown documentation397asd --mode=markdown profile.json398```399400## Advanced Features401402### Structured Documentation with HTML403404For simple descriptions, use plain text in `doc.value`. When you need structured content (lists, definitions, tables), use HTML format:405406```json407{"id": "doCheckout", "type": "unsafe", "rt": "#OrderConfirmation",408 "title": "Complete Checkout",409 "doc": {410 "format": "html",411 "value": "<dl><dt>Behavior</dt><dd>Processes payment, reserves inventory, sends confirmation email</dd><dt>Preconditions</dt><dd>Valid cart with items, payment method configured</dd><dt>Errors</dt><dd>Returns 400 if payment fails or items out of stock</dd></dl>"412 }413}414```415416Format support levels (per ALPS spec):417- `text`: Required (default if not specified)418- `html`: Recommended419- `markdown`: Optional420- `asciidoc`: Optional421422### Links to Related Resources423424Use `link` elements to reference external documentation, schemas, or related resources:425426```json427{"id": "BlogPost", "def": "https://schema.org/BlogPosting",428 "title": "Blog Post",429 "doc": {"value": "User-created article visible to all after publication"},430 "link": [431 {"rel": "help", "href": "https://example.com/docs/blog-api.html", "title": "Blog API Documentation"},432 {"rel": "related", "href": "https://example.com/schemas/post.json", "title": "JSON Schema"}433 ]434}435```436437Link attributes:438- `rel` (required): Relationship type - use IANA Link Relations (`help`, `related`, `profile`, etc.)439- `href` (required): URL to the related resource440- `title` (optional): Human-readable description of the link441- `tag` (optional): Classification tags442443## Tips for Better ALPS4444451. **Start with user journeys** - Map the happy path first, then add alternatives4462. **Be consistent** - Use the same naming pattern throughout4473. **Document transitions** - Explain what each action does and when it's available4484. **Use schema.org** - Link to standard definitions for interoperability4495. **Think about errors** - Add error states and recovery transitions4506. **Consider pagination** - List states should support pagination4517. **Tag descriptors** - Use `tag` attribute to group related descriptors452453## References454455- [ALPS Specification](http://alps.io/spec/)456- [Schema.org](https://schema.org/)457- [app-state-diagram](https://github.com/alps-asd/app-state-diagram)