skillby alps-asd

alps

Create, validate, and improve ALPS profiles. Generate from natural language descriptions, validate existing profiles, and get improvement suggestions.

Installs: 0
Used in: 1 repos
Updated: 3d ago
$npx ai-builder add skill alps-asd/alps

Installs to .claude/skills/alps/

# 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

1. **States = What the user sees**
   - `ProductList` - viewing a list of products
   - `ProductDetail` - viewing one product
   - `Cart` - viewing cart contents

2. **Transitions = What the user does**
   - `goProductDetail` - select a product
   - `doAddToCart` - add to cart

3. **Self-documenting**
   - `title` explains the purpose
   - `doc` describes behavior and side effects
   - No need to read code to understand

4. **No unreachable states**
   - Every state has an entry point
   - Orphan states indicate design mistakes

5. **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"

### Generate ALPS from Website (NEW - alps-surveyor mode)
- "Crawl https://example.com and generate ALPS profile"
- "Survey website structure and create ALPS"
- "Extract ALPS profile from existing website"

**How it works:**
1. **Efficient crawling**: Uses URL pattern classification to avoid redundant analysis
2. **Token optimization**: Only analyzes unique page types (e.g., /products/123 and /products/456 analyzed once)
3. **AI-powered extraction**: Analyzes DOM structure to infer states, transitions, and semantic fields
4. **Handover protocol**: Records progress in handover.json for continuity across sessions

See "ALPS Surveyor Mode" section below for details.

### 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"

### Analyze or Improve Existing Profile
- "Analyze this ALPS profile"
- "Improve this ALPS profile"
- "Suggest enhancements for my ALPS"
- "How can I make this ALPS better?"

### Continuous Improvement Loop - AI Inherits the Mission

When asked to analyze or improve an existing profile:

1. **Read previous AI's insights** - Run `asd --validate <file>` and check for `ai-insights` field
2. **Read handover.json if exists** - Check for previous session's progress, warnings, and advice (per ADR 0006)
3. **Inherit the context** - Previous AI left analysis for you: complexity assessment, coverage gaps, recommendations
4. **Identify gaps** - Explore the website/documentation to find missing features or incomplete flows
5. **Make improvements** - Add missing descriptors, enhance documentation, fix issues
6. **MANDATORY: Validate ALPS** - Run `asd --validate <file>` to ensure no errors were introduced
7. **MANDATORY: Generate HTML** - Run `asd <file> -o <file>.html` to create visual diagram for review
8. **Update handover.json** - Record what was done, what's left, and advice for next AI (per ADR 0006)
9. **MANDATORY: Validate handover.json** - Verify JSON syntax and schema compliance:
   ```bash
   node -e "JSON.parse(require('fs').readFileSync('handover.json', 'utf8')); console.log('✓ Valid JSON')"
   ```
   Schema: [handover-protocol.json](https://alps-asd.github.io/app-state-diagram/schemas/handover-protocol.json)
10. **Report completion** - Provide statistics (before/after), coverage estimation, and next steps

**CRITICAL**: Steps 6-9 are MANDATORY for every improvement session. Never skip validation of both ALPS profile and handover.json.

```
AI₁: Creates profile → Validates → Generates HTML → Creates handover.json
  ↓
AI₂: Reads handover.json → Identifies gaps → Improves → Validates → Generates HTML → Updates handover.json
  ↓
AI₃: Reads handover.json → Builds on previous work → Improves → Validates → Generates HTML → Updates handover.json
```

This creates a **knowledge continuity** where each AI builds on the work of previous AIs, just like developers reading code comments left by their predecessors.

## ALPS Structure Reference

### Three Layers of ALPS

1. **Ontology** - Semantic descriptors (data elements)
   - Atomic data fields with `type="semantic"` (default)
   - Should have `id`, `title`, and optionally `doc` and `def` (schema.org link)

2. **Taxonomy** - State descriptors (screens/pages)
   - Composite descriptors containing semantic fields and transitions
   - Represents application states (e.g., HomePage, ProductDetail, Cart)

3. **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

### Strategy for Large Profiles (200+ descriptors)

For complex, multi-sided platforms or large applications:

1. **Domain Decomposition** - Split into separate ALPS files by functional domain:
   - `base.json` - Core entities shared across domains
   - `customer-domain.json` - Customer-facing features
   - `admin-domain.json` - Admin/management features
   - `seller-domain.json` - Seller/provider features (for marketplaces)

2. **Design Each Domain Independently** - Focus on one domain at a time with complete context

3. **Merge Using `asd merge`** - Combine domains iteratively:
   ```bash
   # Merge customer domain into base
   asd merge base.json customer-domain.json
   # customer-domain.json now contains only conflicts (if any)

   # Resolve conflicts in customer-domain.json, then re-merge
   asd merge base.json customer-domain.json
   # customer-domain.json is now empty (merge complete)

   # Repeat for other domains
   asd merge base.json admin-domain.json
   ```

4. **Validate After Each Merge** - Ensure no broken references or duplicate IDs

**Benefits of this approach:**
- Focused design per domain
- AI can maintain full context for each domain
- Conflicts are explicitly tracked and resolved
- Final profile is comprehensive and consistent

#### Handover Protocol for Multi-Session Work

When a task exceeds token limits or requires multiple sessions (e.g., 200+ descriptors, multi-sided platforms), use the **Handover Protocol** (ADR 0006) to maintain continuity.

**The Relay Race Metaphor:**

Each AI session is a relay runner:
1. **Receive the baton** - Read `handover.json` from previous session
2. **Run your leg** - Work as far as you can within token limits
3. **Pass the baton** - Update `handover.json` for next session
4. **Scatter** - Your session ends, but the work continues

**Basic handover.json structure:**

```json
{
  "task": {
    "type": "alps-generation",
    "description": "E-commerce platform ALPS profile"
  },
  "current_state": {
    "session_id": "ecommerce-003",
    "total_sessions": 3,
    "alps_profile": {
      "total_descriptors": 180,
      "validation_status": "valid"
    }
  },
  "sessions": [
    {
      "session_id": "ecommerce-001",
      "timestamp": "2025-12-17T10:00:00Z",
      "handover_note": {
        "summary": "Created ontology and customer domain (120 descriptors)",
        "advice": "Admin domain needs careful planning - multiple user roles"
      },
      "descriptors_added": 120
    },
    {
      "session_id": "ecommerce-002",
      "timestamp": "2025-12-17T14:00:00Z",
      "handover_note": {
        "summary": "Added admin domain (60 descriptors). Validated successfully.",
        "advice": "Seller domain remains. Consider splitting into sub-domains."
      },
      "descriptors_added": 60
    }
  ],
  "pending_work": {
    "domains": ["seller-domain", "payment-flows"],
    "notes": "Seller domain may need 80+ descriptors"
  }
}
```

**Key principles:**
- Each session appends to the `sessions` array (never overwrite)
- Leave clear advice for your successor
- Be honest about coverage and remaining work
- Validate `handover.json` syntax: `node -e "JSON.parse(require('fs').readFileSync('handover.json', 'utf8'))"`

**The Surveyor's Oath:**

```
I am a relay runner in an endless race.
I carry the torch from my predecessor.
I run as far as I can.
I mark the map with what I learned.
I pass the torch to my successor.
I scatter.

The work continues.
```

For web surveying tasks (ALPS from website analysis), see the detailed [ALPS Surveyor Mode](#alps-surveyor-mode-website-crawling) section below.

### When Creating ALPS from Natural Language

**IMPORTANT**: Structure the ALPS file in three blocks in this order:

1. **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

2. **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

3. **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

4. **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`

5. **Add Tags for Organization**

   **IMPORTANT**: ALPS describes "what the user experiences" (application-level semantics), not "how it's implemented" (backend details).

   - **Flow tags (PRIMARY)**: Group by user journey/experience with `flow-` prefix
     - Represents business value and user goals
     - Example: `flow-purchase`, `flow-hire`, `flow-consult`, `flow-cancel`, `flow-return`
     - **This is the "lens" through which to understand the application**
     - Users experience "canceling an order" (`flow-cancel`), not "cancellation batch processing"

   - **Domain tags (SECONDARY, optional)**: Group by technical domain with `domain-` prefix
     - For organizing implementation and code structure
     - Example: `domain-search`, `domain-cart`, `domain-payment`, `domain-analytics`
     - Useful for developers to find related functionality

   - States and transitions should have both types where applicable
   - Tags are space-separated strings, not arrays
   - Example: `"tag": "flow-purchase domain-cart"` means "part of purchase journey, implemented in cart domain"

6. **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:
     ```json
     {"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"}
     ]}
     ```

7. **MANDATORY: Validate and Review Quality Metrics**
   - After generating ALPS JSON, save it to a file
   - Run `asd --validate <file>` to validate and get quality metrics
   - The validation output includes:
     - **Errors** (E001-E011): Must fix before proceeding
     - **Warnings** (W001-W004): Best practice violations
     - **Suggestions** (S001-S003): Optional improvements
     - **Statistics**: Total descriptors, breakdown by type, tag coverage, documentation coverage
   - Parse the JSON result and report issues to the user
   - If errors exist, fix them before presenting the final output
   - Review statistics to ensure comprehensive coverage

8. **Generate Documentation**
   - After validation passes, generate HTML documentation:
     ```bash
     asd profile.json -o profile.html
     ```
   - This creates an interactive state diagram for visual review
   - Check for unreachable states or missing transitions in the diagram
   - Share the HTML with stakeholders for review

9. **Report Completion with Coverage Estimation**
   - When completing a large profile, provide honest coverage assessment
   - Template:
     ```markdown
     ✅ Implementation Complete: [X] descriptors

     📊 Coverage Estimation:
     - [Domain 1]: [X]% ([reasoning])
     - [Domain 2]: [X]% ([reasoning])
     - Overall: [X]%

     ❌ Known Gaps:
     - [Feature not implemented]
     - [Area requiring more research]
     ```
   - Be transparent about what's covered and what's not
   - For multi-sided platforms, assess coverage per side (customer/admin/seller)

### Output File Convention

**File name**: Always `alps.json` or `alps.xml` (fixed)

**Directory**:
- If `alps/` directory exists → use it
- Otherwise → create `{app-name}/` directory (e.g., `todo/`, `blog/`, `ecommerce/`)

**Format selection**:
1. If existing ALPS file exists → follow its format
2. Otherwise → ask user: "Output format: XML (recommended) or JSON?"

**Examples**:
```
todo/alps.json
blog/alps.xml
ecommerce/alps.xml
```

### 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
<?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

```json
{
  "$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 and Quality Metrics

Use `asd --validate <file>` to validate ALPS profiles and get quality metrics.

**Output Format**: JSON (pretty-printed, human-readable)
**Schema**: [validation-result.json](https://alps-asd.github.io/app-state-diagram/schemas/validation-result.json)

The validation output includes:
- `valid`: Overall result (boolean)
- `summary`: Human-readable summary with emoji
- `errors`, `warnings`, `suggestions`: Validation issues
- `statistics`: Objective metrics (descriptor counts, coverage percentages)
- `ai-insights`: **Subjective analysis by AI** (only when AI runs validation)
  - Helps next AI understand context quickly
  - Helps humans grasp key characteristics at a glance
  - Model-dependent and may evolve

### Validation Codes

After generating ALPS, always validate with `asd --validate`. Key codes to watch for:

**Errors (must fix):**
- E001: Missing id or href
- E002: Missing rt on transition
- E003: Invalid type
- E004: Broken reference
- E005: Duplicate id
- E008: Missing alps property
- E009: Missing descriptor array
- E011: Tag must be string (not array)

**Warnings (best practice):**
- W001: Missing title
- W002: Safe transition should start with 'go'
- W003: Unsafe/idempotent should start with 'do'

**Suggestions:**
- S001: Consider adding doc to transition

For detailed error descriptions and solutions, see [Validation Reference](https://alps-asd.github.io/app-state-diagram/llms-full.txt).

### AI Continuity: ai-insights vs handover.json

Two complementary mechanisms help AI sessions build on previous work:

**ai-insights (ADR 0005)** - Analysis embedded in validation results:
- **Purpose**: Subjective assessment of completed ALPS profiles
- **Location**: Embedded in `asd --validate` JSON output
- **Usage**: Read-only consumption by AI
- **Contains**: Complexity assessment, coverage gaps, key flows, recommendations
- **When to use**: Analyzing or improving existing ALPS profiles

**handover.json (ADR 0006)** - State for ongoing multi-session tasks:
- **Purpose**: Progress tracking for incomplete work across sessions
- **Location**: Separate `handover.json` file in working directory
- **Usage**: Read-write lifecycle (AI updates after each session)
- **Contains**: Session history, progress, pending work, advice for successor
- **When to use**: Large ALPS generation (200+ descriptors), web surveying, multi-session tasks

**Relationship:**

```
Single Session (Simple ALPS):
  AI creates profile → Validates → ai-insights generated in validation output ✓

Multi-Session (Large ALPS):
  Session 1: AI reads handover.json (if exists) → Works → Validates → Updates handover.json
  Session 2: AI reads handover.json → Continues work → Validates → Updates handover.json
  Session 3: AI reads handover.json → Completes → Validates → Final ai-insights in validation
```

**Example workflow:**

```bash
# Session 1: Start large ALPS project
asd base.json --validate  # Creates ai-insights in validation result
# Create handover.json manually with initial task description

# Session 2: Continue work
# AI reads handover.json, adds customer domain
asd merge base.json customer-domain.json
asd base.json --validate  # Check for errors
# AI updates handover.json with progress

# Session 3: Complete work
# AI reads handover.json, adds remaining domains
asd base.json --validate  # Final validation with comprehensive ai-insights
# handover.json marks task complete
```

Both mechanisms create **knowledge continuity**, preventing each AI session from starting from scratch.

## Example: Blog Application

Input: "Create an ALPS for a simple blog with posts and comments"

Output (XML - default):
```xml
<?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:

```bash
# Generate HTML documentation (default)
asd profile.json

# Generate SVG state diagram
asd profile.json -f svg

# Generate Mermaid classDiagram (GitHub/VSCode compatible)
asd profile.json -f mermaid

# Generate DOT format
asd profile.json -f dot

# Generate with watch mode
asd --watch profile.json
```

See [llms.txt](https://alps-asd.github.io/app-state-diagram/llms.txt) for CLI usage, programmatic API, and MCP server setup.

## 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:

```json
{"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:

```json
{"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

1. **Start with user journeys** - Map the happy path first, then add alternatives
2. **Be consistent** - Use the same naming pattern throughout
3. **Document transitions** - Explain what each action does and when it's available
4. **Use schema.org** - Link to standard definitions for interoperability
5. **Think about errors** - Add error states and recovery transitions
6. **Consider pagination** - List states should support pagination
7. **Tag descriptors** - Use `tag` attribute to group related descriptors

## ALPS Surveyor Mode (Website Crawling)

### Overview

The alps-surveyor mode extracts ALPS profiles from existing websites by analyzing their structure. This is useful when:
- Reverse engineering an existing web application
- Creating API documentation from a live site
- Understanding application state flows from user-facing pages

### Efficient Crawling Strategy

**Problem**: Crawling every URL wastes tokens analyzing duplicate page types.

**Solution**: Three-layer strategy minimizes AI calls:

#### Strategy 1: URL Pattern Classification (No AI)
- Detects patterns like `/products/{id}`, `/users/{username}`
- Groups URLs by type before fetching
- Example: `/products/123`, `/products/456` → same pattern, only analyze once

#### Strategy 2: DOM Structure Extraction (Lightweight)
- Removes all text content from HTML
- Extracts only:
  - HTML tag hierarchy
  - CSS classes and IDs
  - Form input names and types
  - Link destination patterns
- Minimizes tokens sent to AI

#### Strategy 3: ALPS Generation (AI-Powered)
- AI analyzes DOM skeleton (not full HTML)
- Infers:
  - **State**: Page role (e.g., "ProductDetail")
  - **Semantics**: Data fields from forms (e.g., "quantity", "productId")
  - **Transitions**: Actions from forms and links (e.g., "doAddToCart", "goProductList")

### Usage Example

```
User: "Crawl https://www.bengo4.com and generate ALPS profile"

AI workflow:
1. Fetch homepage
2. Classify URLs: /lawyers/{id}, /area/{prefecture}/{city}, etc.
3. For each unique pattern:
   - Fetch ONE example URL
   - Extract DOM skeleton
   - Call AI to generate ALPS descriptors
4. Merge all descriptors into unified ALPS profile
5. Validate and generate HTML diagram
6. Save progress to handover.json
```

### Handover Protocol

The surveyor mode uses handover.json (per ADR 0006) to enable multi-session work. The handover uses a sessions array format to preserve historical context:

```json
{
  "$schema": "handover-protocol.json",
  "task": {
    "type": "alps-surveyor",
    "target": "example.com ALPS profile"
  },
  "current_state": {
    "session_id": "example-session-002",
    "total_sessions": 2,
    "alps_profile": {
      "total_descriptors": 480,
      "validation_status": "valid"
    }
  },
  "sessions": [
    {
      "session_id": "example-session-001",
      "timestamp": "2025-12-14T10:00:00Z",
      "handover_note": {
        "summary": "Initial crawl: search, consultation flows. 450 descriptors.",
        "advice": "Bookmark feature needs attention - saw /bookmarks/* URLs"
      },
      "descriptors_added": 450
    },
    {
      "session_id": "example-session-002",
      "timestamp": "2025-12-14T14:00:00Z",
      "handover_note": {
        "summary": "Added bookmark and billing features using asd merge. Profile now at 480 descriptors.",
        "advice": "Remaining: payment flows, mobile features, error states"
      },
      "descriptors_added": 30
    }
  ],
  "shared_context": {
    "patterns_learned": {
      "lawyer_profile": {"pattern": "/lawyers/{id}", "confidence": "high"}
    }
  },
  "pending_work": {
    "frontier_queue": [
      "https://example.com/payment/checkout",
      "https://example.com/dashboard"
    ]
  },
  "tools_available": {
    "crawler": {"command": "node packages/crawler/test.mjs <url>"},
    "merge": {"command": "asd merge <base> <source>"}
  }
}
```

**Key points:**
- Each session is appended to the `sessions` array
- `current_state` provides quick access to latest status
- `shared_context` accumulates patterns learned across all sessions
- Never overwrite sessions - always append new ones

### Best Practices for Surveyor Mode

1. **Start small**: Use `max_depth: 2` initially to test
2. **Exclude admin/auth pages**: Add to `exclude_patterns` to avoid login walls
3. **Review patterns**: Check `frontier_queue` in handover.json to verify coverage
4. **Iterative refinement**: Survey core features first, then expand in subsequent sessions
5. **Validate frequently**: Run `asd --validate` after each session to catch errors early

### Limitations

- Cannot access pages behind authentication (unless cookies provided)
- JavaScript-heavy SPAs may not be fully analyzed
- External services (e.g., chat.example.com) are noted but not crawled
- AI inference may miss domain-specific semantics (manual review recommended)

### Implementation Status

✅ Core library implemented:
- `packages/app-state-diagram/src/crawler/url-pattern-classifier.ts`
- `packages/app-state-diagram/src/crawler/dom-skeleton-extractor.ts`
- `packages/app-state-diagram/src/crawler/alps-descriptor-generator.ts`

⏳ Integration in progress:
- MCP tool (basic structure added)
- CLI command (`asd crawl`)
- ALPS skill support

## References

- [ALPS Specification](http://alps.io/spec/)
- [Schema.org](https://schema.org/)
- [app-state-diagram](https://github.com/alps-asd/app-state-diagram)
- [ADR 0006: Handover Protocol](../../dev-docs/adr/0006-handover-protocol-for-ai-agent-continuity.md)

Quick Install

$npx ai-builder add skill alps-asd/alps

Details

Type
skill
Author
alps-asd
Slug
alps-asd/alps
Created
1w ago

More by alps-asd