Skip to content

Latest commit

 

History

History
532 lines (378 loc) · 12 KB

File metadata and controls

532 lines (378 loc) · 12 KB

AISD Best Practices

Organization patterns for AI-generated documentation

Note: AISD docs are generated by AI from human requirements, not hand-written. These patterns guide AI when structuring docs and help humans navigate AI-generated content.

Example references: Use model.md for illustration. In practice, use TypeScript/JSON Schema for models (authoritative), use AISD for business rules/constraints (AI-generated).


Organization Principles

AI writes docs, AI reads docs, humans review diffs.

Optimize for:

  1. Context precision - AI loads exactly what's needed for the task
  2. Selective loading - Small files enable mixed context composition
  3. Single responsibility - One concept per file prevents over-loading
  4. No cascading dependencies - Self-contained files, no chain loading
  5. Index-based navigation - AI orients without reading full specs

File Organization

Example Directory Structure

docs/
├── index.md              # System overview (<100 lines)
├── architecture.md       # High-level design (200-500 lines)
├── domain-a/
│   ├── index.md          # Domain overview (<100 lines)
│   ├── model.md          # Entities (200-500 lines)
│   └── behavior.md       # Operations (200-500 lines)
├── domain-b/
│   ├── index.md
│   ├── model.md
│   └── behavior.md
└── adr/
    ├── 0001-decision.md  # Architectural Decision Record
    └── 0002-decision.md

Directory Types

Directory Purpose Contains
docs/ Root documentation index.md, architecture.md
docs/domain-name/ Domain-specific docs index.md, model.md, behavior.md
docs/adr/ Architecture decisions ADR files (numbered)

Hierarchical Organization

Three-Level Structure

Level 1: System (docs/index.md)

  • System overview
  • All domains listed
  • High-level architecture
  • <100 lines

Level 2: Domain (docs/domain/index.md)

  • Domain purpose
  • Entities listed
  • Operations listed
  • Links to specs
  • <100 lines

Level 3: Specs (docs/domain/*.md)

  • Full entity definitions (model.md)
  • Complete operation specs (behavior.md)
  • Integration details (integration.md)
  • 200-500 lines each

Example: System Index

# System Overview

**Purpose**: Task management system

## Domains

- **tasks/** - Core task entities and operations
- **users/** - User management and authentication
- **notifications/** - Notification delivery

## Architecture

See [architecture.md](architecture.md) for system design.

Example: Domain Index

# Tasks Domain

**Purpose**: Manage todo tasks with priorities

## Entities

- **Task** - Todo item with status and priority

## Operations

- **CreateTask** - Create new task
- **UpdateTaskStatus** - Change task status
- **GenerateDailyList** - Generate daily todo list

## Files

- **model.md** - Task entity definition
- **behavior.md** - Task operations

AI value:

  • Without index: AI must read full spec files to understand domain scope
  • With index: AI reads small index file, knows domain contents and which file to load
  • Use case: "What domains exist?" → Load all index files instead of all specs

Domain Isolation

Purpose: Enable AI to load precise context without cascading dependencies

Not about: Architectural purity or project size

About: Context precision - AI loads exactly what's needed, nothing more

Preventing Context Cascade

Domains MUST NOT directly reference entities from other domains.

Bad (cross-domain coupling):

# User

| Field | Type |
|-------|------|
| id | UUID |
| orders | List[Order] |  ← Direct reference to Order entity

Problem: AI loading User entity must also load Order entity to understand type Cascade: User → Order → Product → Category → ... (context explosion)

Good (primitive references):

# User

| Field | Type |
|-------|------|
| id | UUID |
| order_ids | List[UUID] |  ← Primitive type only

Benefit: User entity is self-contained, no cascade loading required

Integration Files

Use integration.md to document cross-domain relationships without coupling.

Example (docs/users/integration.md):

# User Integration

## Orders Integration

**Relationship**: User has many Orders (1:N)

**User side**:
- User has field: order_ids (List[UUID])
- User MUST NOT know Order internals

**Orders side**:
- Order has field: user_id (UUID)
- Order queries User via user_id

**API**: User service provides GetUserOrders(user_id) → List[UUID]

Context Loading Strategy

AI Context Budget

Typical AI context windows: 8k-200k tokens

File size targets optimized for context:

  • Index: <100 lines (~500 tokens)
  • Spec: 200-500 lines (~1500-3000 tokens)
  • Max: 1000 lines (~6000 tokens)

Loading Patterns

Task Load Token Budget Files Loaded
System overview All indexes ~2k docs/*/index.md
Single domain work One domain ~4k docs/domain/*.md
Cross-domain work Two domains ~8k docs/domain-a/*.md, docs/domain-b/integration.md
Bug fix Single spec ~1.5k docs/domain/behavior.md

Example: Feature Implementation

Task: Add "due dates" to tasks

Load:

  1. docs/tasks/index.md (orientation)
  2. docs/tasks/model.md (see current fields)
  3. docs/tasks/behavior.md (see operations to update)

Don't load:

  • docs/users/*.md (not needed)
  • docs/notifications/*.md (not needed)
  • docs/architecture.md (too high-level)

Result: ~4k tokens, focused context

Example: Integration Work

Task: Send notification when task is created

Load:

  1. docs/tasks/behavior.md (CreateTask operation)
  2. docs/notifications/behavior.md (SendNotification operation)
  3. docs/tasks/integration.md (how tasks trigger notifications)

Don't load:

  • docs/tasks/model.md (already know Task structure)
  • docs/users/*.md (not relevant)

Result: ~6k tokens, relevant context only


File Size Management

When to Split Files

Not about project size - about context precision

Wrong question: "Is my project big enough to need split files?" Right question: "Will AI need to load these concepts together or separately?"

Split when:

  • Concepts used independently (User vs Role vs Permission - load separately)
  • File exceeds 500 lines
  • AI would over-load context for simple tasks

Keep together when:

  • Concepts always used together (Cart + CartItem + Checkout - always co-loaded)
  • Total <500 lines
  • Splitting creates no context loading benefit

How to split:

By domain:

before: tasks-and-users-model.md (800 lines)
after:  tasks/model.md (400 lines)
        users/model.md (400 lines)

By concern:

before: tasks/model.md (700 lines with validation rules)
after:  tasks/model.md (350 lines - just entities)
        tasks/validation.md (350 lines - validation rules)

By operation:

before: tasks/behavior.md (900 lines - all operations)
after:  tasks/create-operations.md (300 lines)
        tasks/update-operations.md (300 lines)
        tasks/query-operations.md (300 lines)

Context Loading Examples

Example 1: Split files enable selective loading

Task: "Add due dates to tasks"

Large file approach:

docs/model.md (all entities in one file)
AI loads: Entire file including User, Task, Tag, Comment, Attachment

Small file approach:

docs/tasks/model.md
AI loads: Only Task entity

Example 2: Mixed context composition

Task: "Send notification when task assigned to user"

Load:

  • tasks/model.md (task fields)
  • users/behavior.md (how to notify)
  • notifications/behavior.md (notification operations)

Don't load:

  • users/model.md (don't need user fields)
  • tasks/behavior.md (not creating tasks)
  • Tag, Comment, Attachment files

This precise mixing impossible with multi-responsibility files


Linking and Navigation

Index-Style Linking (Preferred)

Use bold filename followed by description.

## Related

- **model.md** - Task entity definitions
- **behavior.md** - Task operations
- **../users/model.md** - User entity definitions

Benefits:

  • Scannable
  • Works well in AI-generated lists
  • Clear relationship to file structure

Inline Linking

Use for prose references.

See [model.md](model.md) for Task entity fields.

Integration with users documented in [../users/integration.md](../users/integration.md).

Cross-References Rules

Within same directory:

[model.md](model.md)

Parent directory:

[../index.md](../index.md)

Sibling directory:

[../users/model.md](../users/model.md)

Never use absolute paths:

[/docs/users/model.md](/docs/users/model.md)[../users/model.md](../users/model.md)

Anti-Patterns

❌ Bad Organization

1. Monolithic files:

docs/
└── everything.md (3000 lines)

Why bad: Exceeds context limits, mixes concerns, hard to navigate

2. No hierarchy:

docs/
├── task-entity.md
├── user-entity.md
├── create-task.md
├── update-task.md
├── create-user.md
└── login-user.md

Why bad: Flat structure, no domain isolation, hard to find related files

3. Cross-domain coupling:

# User (in docs/users/model.md)

| Field | Type |
|-------|------|
| current_task | Task |  ← Directly references Task entity

Why bad: Domains tightly coupled, can't load users without tasks

4. Implementation in specs:

# CreateTask

Store task in PostgreSQL using SQLAlchemy ORM.
Use connection pool with max 10 connections.

Why bad: Spec should describe behavior, not implementation

✅ Good Organization

1. Hierarchical structure:

docs/
├── index.md
├── tasks/
│   ├── index.md
│   ├── model.md
│   └── behavior.md
└── users/
    ├── index.md
    ├── model.md
    └── behavior.md

2. Domain isolation with integration:

# User (in docs/users/model.md)

| Field | Type |
|-------|------|
| task_ids | List[UUID] |  ← Primitive reference only

# Integration (in docs/users/integration.md)

User has many Tasks via task_ids

3. Behavior-only specs:

# CreateTask

**Preconditions**: Title MUST be 1-200 characters

**Actions**:
1. Generate UUID
2. Set status to "pending"
3. Store task persistently

**Postconditions**: Task persists across application restarts

Validation

Directory Structure Check

# Check for index.md in each domain directory
for dir in docs/*/; do
  if [ ! -f "$dir/index.md" ]; then
    echo "Missing index.md in $dir"
  fi
done

File Size Check

# Find files exceeding 500 lines
wc -l docs/**/*.md | awk '$1 > 500 {print $2 ": " $1 " lines (max 500)"}'

Broken Link Check

# Check for broken markdown links (requires markdown-link-check)
find docs/ -name "*.md" -exec markdown-link-check {} \;

Quick Reference

Directory structure:

docs/
├── index.md (<100 lines)
├── domain-name/
│   ├── index.md (<100 lines)
│   ├── model.md (200-500 lines)
│   └── behavior.md (200-500 lines)

File sizes:

  • Index: <100 lines
  • Spec: 200-500 lines
  • Max: 1000 lines (split if exceeded)

Domain isolation:

  • Use primitive types (UUID, String) for cross-domain references
  • Use integration.md to document domain bridges
  • Never directly reference entities from other domains

Context loading:

  • System overview: Load all indexes (~2k tokens)
  • Single domain: Load one domain (~4k tokens)
  • Integration: Load 2-3 domains (~8k tokens)

Related


Back to: README.md for standard overview.