Files
dss/docs/01_core/BEST_PRACTICES.md
Digital Production Factory 276ed71f31 Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm

Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)

Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability

Migration completed: $(date)
🤖 Clean migration with full functionality preserved
2025-12-09 18:45:48 -03:00

20 KiB

DSS Best Practices & Implementation Guide

Version 1.0.0 | Last Updated: 2025-12-08 | Status: Production

This document explains how to apply the 5 core principles in daily work. See PRINCIPLES.md for what the principles are; this document shows how to implement them.


Principle 1: Design is an Architectural Concern

How to Apply

1.1 Treat Design Tokens as Code Dependencies

Design tokens (colors, spacing, typography) are not styling suggestions—they're contracts that code depends on.

❌ WRONG:
<!-- Using hex values directly -->
<Button style={{ background: "#007AFF" }} />

✅ RIGHT:
<!-- Using design token from contract -->
<Button background={tokens.color.primary[500]} />

Checklist:

  • All color values come from token definitions
  • All spacing values come from token definitions
  • All typography values come from token definitions
  • Components reference tokens, not hardcoded values
  • Token schema documented in tokens/ directory
  • Tokens versioned with semantic versioning

Enforcement:

# Pre-commit check: No hardcoded hex colors in component code
grep -r "#[0-9A-F]{6}" packages/components/ && exit 1

1.2 Design Changes Follow Same Review as API Changes

A design change that affects components requires the same rigor as an API change.

Component Update Example:
Old Contract: Button[variant=primary] uses color.primary[500]
New Contract: Button[variant=primary] uses color.primary[600]

Requires:
✅ Version bump in component spec
✅ Migration guide for consumers
✅ Changelog entry
✅ 6-month deprecation notice for old version

Checklist:

  • Design change documented in ARCHITECTURE.md
  • Component contract updated with version
  • Migration path provided if breaking
  • Changelog entry created
  • Deprecation timeline documented

1.3 Make Visual Decisions Explicit

Every design decision should be traceable back to why (not "looks good").

❌ "Changed button color to blue"
✅ "Changed button color from color.primary[500] to color.primary[600]
    for improved contrast on light backgrounds (WCAG AA compliance)"

Checklist:

  • Design decisions documented in ADR
  • Visual change rationale explained
  • Alternatives considered documented
  • Impact assessment done
  • Accessibility implications checked

Red Flags

❌ "Let me just tweak this spacing"
   → Is it breaking a contract? Document the change

❌ Figma file has one value, component has another
   → Single source of truth violation; reconcile immediately

❌ "Designers will use Figma, developers will use tokens"
   → Should be the same source (tokens in Figma, imported to code)

❌ Visual change not documented in ARCHITECTURE.md
   → Architectural decisions should be explicit

Principle 2: Contracts are Immutable and Versioned

How to Apply

2.1 Understand Semantic Versioning

MAJOR.MINOR.PATCH  (e.g., 1.2.3)

PATCH (1.2.3 → 1.2.4):
- Documentation fixes
- Bug fixes
- Non-breaking improvements
- Examples: typo fix, clarity improvement

MINOR (1.2.3 → 1.3.0):
- New features/endpoints
- New optional fields
- Backwards compatible additions
- Examples: new Button variant, new optional parameter

MAJOR (1.2.3 → 2.0.0):
- Breaking changes only (rare)
- Removed endpoints
- Changed schemas
- Changed behavior
- Examples: remove deprecated endpoint, change auth scheme

Checklist:

  • All Tier 1 files have version numbers (API_CONTRACTS.md, ARCHITECTURE.md)
  • Version follows semver (MAJOR.MINOR.PATCH)
  • Every change bumps appropriate version level
  • Changelog entry created for each version
  • Breaking changes documented in migration guide
  • Deprecation timeline provided (6+ months notice)

2.2 Version Control Workflow

Step 1: Make change to contract
        ↓
Step 2: Bump version in file header
        ↓
Step 3: Add changelog entry (what changed, why, migration path)
        ↓
Step 4: Open PR with version change
        ↓
Step 5: PR reviewed (breaking changes require extra scrutiny)
        ↓
Step 6: Merge and tag with version (git tag v1.3.0)
        ↓
Step 7: Update dependent systems

Checklist:

  • Version bumped BEFORE merge (not after)
  • Changelog file updated with new version
  • Git tag created (git tag v1.2.4)
  • Dependent projects notified of breaking changes
  • Migration guide provided if needed
  • Old version archived in docs/archive/versions/

2.3 Deprecation Pattern

When you need to remove something:

v1.2.0: Introduce deprecation notice
  "Endpoint GET /api/v1/projects/{id} deprecated as of v1.2.0"
  "Will remove in v2.0.0 (projected Q2 2026)"
  "Migration: See MIGRATION_GUIDE.md"

v1.3.0 - v1.9.9: Endpoint still works, warning on use
  Agents can query mcp_tool_usage table and see deprecation warnings

v2.0.0: Remove deprecated endpoint
  Removed entirely (breaking change, MAJOR bump)
  Old version documented in docs/archive/versions/v1.9.9/

Checklist:

  • Deprecation notice added to contract
  • Sunset date documented (minimum 6 months)
  • Migration guide provided
  • Warning emitted when deprecated feature used
  • Period passed before removal
  • Removal is major version bump

Red Flags

❌ API_CONTRACTS.md changed but version didn't change
   → Every change = version bump required

❌ "We'll update the version after release"
   → Version should be updated before merge

❌ Endpoint removed without deprecation period
   → Breaks contract immutability; should have been deprecated first

❌ Breaking change in a minor version
   → Only non-breaking changes in MINOR bumps

Principle 3: The System is the Single Source of Truth

How to Apply

3.1 One Canonical Location Rule

Information Type        | Canonical Location
------------------------|----------------------------------
API endpoint specs      | API_CONTRACTS.md (Tier 1)
Architecture decisions  | ARCHITECTURE.md (Tier 1)
Project status          | PROJECT_STATUS.md (Tier 2)
Feature inventory       | IMPLEMENTATION_SUMMARY.md (Tier 2)
Implementation guides   | docs/03_reference/GUIDES/ (Tier 3)
Historical snapshots    | docs/archive/ (Tier 4)
Why decisions were made | .knowledge/adrs/ (Decision records)

Checklist:

  • Each piece of info has ONE canonical location
  • No duplicate specs in multiple files
  • Other docs link to canonical source, not copy content
  • Tier 1 files are immutable (semver only)
  • Tier 2 files updated weekly
  • Tier 3 docs reference Tier 1 (not duplicate)

3.2 Link Instead of Copy

❌ WRONG (duplication):
README.md:
  "Supported auth methods: OAuth, JWT, API Key"

ARCHITECTURE.md:
  "Supported auth methods: OAuth, JWT, API Key"

✅ RIGHT (single source):
README.md:
  "See ARCHITECTURE.md for supported auth methods"

ARCHITECTURE.md:
  "Supported auth methods: OAuth, JWT, API Key"

Checklist:

  • Never copy-paste specifications between files
  • Use markdown links when referencing specs
  • Links updated when target moves
  • Broken links detected by CI/CD (link-rot check)

3.3 Conflict Resolution: Find the Real Source

When two docs say different things:

Step 1: Identify conflict
        "Status says Figma sync works (PROJECT_STATUS.md)"
        "API_CONTRACTS.md says GET /sync has 30s timeout"

Step 2: Find canonical source
        Tier 1 (ARCHITECTURE.md) is more authoritative than Tier 2
        Real truth is in the code

Step 3: Fix the summary
        PROJECT_STATUS.md should say:
        "Figma sync works (30s timeout limit)"

Step 4: Update both sources
        Summary = simplified truth
        Spec = full truth
        They must align

Checklist:

  • Identify which source is authoritative (Tier level)
  • Update all copies to match truth
  • Add cross-reference explaining difference
  • Document conflict resolution in ADR

Red Flags

❌ "Also see DEPLOYMENT_GUIDE.md for full endpoint spec"
   → Spec should be ONLY in API_CONTRACTS.md

❌ Three different status files: MVP_STATUS, PHASE_5_REPORT, PROJECT_STATUS
   → Keep PROJECT_STATUS.md only; archive others

❌ README.md repeats API endpoints from API_CONTRACTS.md
   → README links to API_CONTRACTS.md instead

❌ Component spec in Figma file AND Storybook AND Component.md
   → Single source: Storybook is canonical; Figma links to it

Principle 4: Decisions are Explicit and Traceable

How to Apply

4.1 Create Architecture Decision Records (ADRs)

Every significant architectural decision should have an ADR in .knowledge/adrs/.

---
id: 001
title: Token Merge System as Core DSS Feature
date: 2025-12-05
author(s): Team Name
status: Accepted
principles: [Design is Architectural, Contracts Immutable, Single Source of Truth]
related:
  - doc: docs/01_core/ARCHITECTURE.md#token-merge
  - adr: ADR-002-MCP-first-architecture
  - ticket: DSS-PR-101
---

## Context
Multiple projects needed to ingest tokens from Figma, CSS, SCSS...

## Decision
Implement TokenMerger class with pluggable merge strategies...

## Alternatives Considered
1. Manual token mapping → Doesn't scale
2. Single canonical strategy → Too rigid

## Consequences
**Positive:**
- Flexible: Teams choose their strategy
- Non-destructive: Conflict reports

**Negative:**
- More complex than single strategy
- Developers must understand each strategy

Checklist:

  • ADR created for significant decisions
  • Context section explains why decision matters
  • Alternatives section documents what was considered
  • Consequences section lists pros and cons
  • Related links connect to docs and code
  • Status is Proposed → Accepted → (Deprecated/Superseded)
  • Linked from PR that implements decision

4.2 Link Code to Decisions

In commit messages and PRs, reference the ADR:

Bad:
  commit: "Add token merge strategies"

Good:
  commit: "feat: Add token merge strategies (implements ADR-001)

          TokenMerger class supports FIRST, LAST, PREFER_FIGMA,
          PREFER_CODE, PREFER_SPECIFIC strategies.

          See ADR-001 for rationale and alternatives."

PR Description:
  "## ADR Link
   Implements decision in ADR-001

   ## Principle Alignment
   - Principle 1: Design decisions are architectural
   - Principle 3: Token merge is Single Source of Truth
   - Principle 4: Decision recorded for traceability"

Checklist:

  • Commit messages reference ADR (if architectural change)
  • PR description includes ADR link
  • Code comments point to ADR for rationale
  • ADR status updated (Proposed → Accepted)
  • Decision traceable: PR → ADR → Code

4.3 Query Decisions

# Find all decisions about token handling
grep -r "token" .knowledge/adrs/ --include="*.md"

# Find all decisions made by a specific author
grep -r "author.*Alice" .knowledge/adrs/

# Find deprecated decisions
grep -r "status.*Deprecated" .knowledge/adrs/

# Find decisions related to a principle
grep -r "principle.*Design is Architectural" .knowledge/adrs/

Checklist:

  • ADRs organized in .knowledge/adrs/
  • Easy to search and query ADRs
  • ADRs linked from related code/docs
  • When reconsidering decision, old ADR shows previous reasoning

Red Flags

❌ "We decided to use JWT for auth" (no ADR)
   → Should be documented: why JWT? what alternatives?

❌ Design decision only in commit message
   → Lost when history is cleaned up; should be in ADR

❌ Component contract changed without ADR
   → Architectural decision needs documentation

❌ "Why did we do this?" requires reading git logs
   → Indicates decision wasn't documented in ADR

Principle 5: Operations are Exposed as Standardized Tools

How to Apply

5.1 Tool-First Architecture

WRONG (REST-first):
  Agent → MCP tool wrapper → REST endpoint → Database
  Problem: Extra layer, agent waits for HTTP

RIGHT (Tool-first):
  Agent → MCP tool → Database
  Human UI → MCP tool → Database
  (REST endpoint wraps tool, just a thin layer)

Key difference:
- Tools are primary (agents use directly)
- REST is secondary (UI convenience layer)

Checklist:

  • All major operations have MCP tool equivalents
  • Tools are primary implementation (not wrappers)
  • REST endpoints wrap tools (thin layer)
  • Tool input/output documented in JSON Schema
  • Tools versioned (match API_CONTRACTS.md version)
  • All tool calls logged in audit trail
  • Agents can discover tools via introspection

5.2 Design MCP Tool Correctly

# WRONG: Tool calls REST endpoint
class ProjectTools:
    async def dss_create_project(self, name, root_path):
        # Calls REST endpoint, extra hop
        response = await http.post("/api/projects", {...})
        return response.json()

# RIGHT: Tool does the work, REST wraps tool
class ProjectTools:
    async def dss_create_project(self, name, root_path):
        # Tool does work directly
        project = await db.insert_project(name, root_path)
        await log_mcp_tool_usage("dss_create_project", {...})
        return project

# REST endpoint wraps tool
@app.post("/api/projects")
async def create_project(request):
    return await tools.dss_create_project(
        request.json["name"],
        request.json["root_path"]
    )

Checklist:

  • Tool implementation is the primary logic
  • Tool directly accesses data layer (database, files)
  • Tool includes input validation
  • Tool logs usage to audit trail
  • Tool returns structured response (not HTTP wrapper)
  • REST endpoint wraps tool (simple delegation)

5.3 Tool Versioning

Tool versions must match API_CONTRACTS.md version:

When API_CONTRACTS.md says v1.2.0:
  All tools must be v1.2.0
  Tool schema matches API schema
  Breaking changes in tools = breaking API changes

Tool versioning rules:
  MAJOR: Remove parameter, change behavior
  MINOR: Add optional parameter, new tool
  PATCH: Fix bug, improve error message

Checklist:

  • Tool version in code matches API_CONTRACTS.md
  • Tool schema matches API schema
  • Breaking tool changes = breaking API changes (major bump)
  • Tool changelog entries for each version
  • Deprecation path documented for tool changes

5.4 Tool Audit Trail

Every tool call logged with:
  - Tool name (dss_create_project)
  - Timestamp (2025-12-08T10:30:45Z)
  - Caller (agent name, user ID, or "anonymous")
  - Input parameters (name: "my-project", ...)
  - Output (project_id: 123, success: true)
  - Errors (if any)

Example table:
CREATE TABLE mcp_tool_usage (
  id SERIAL PRIMARY KEY,
  tool_name VARCHAR(255),
  timestamp TIMESTAMP,
  caller_type VARCHAR(50), -- "agent", "user", "system"
  caller_id VARCHAR(255),
  input_json JSONB,
  output_json JSONB,
  error_message TEXT,
  duration_ms INT
);

Checklist:

  • Tool call audit table exists
  • Every tool call logged with parameters
  • Audit trail queryable (who used what, when)
  • Errors captured in audit trail
  • Tool performance tracked (duration)

Red Flags

❌ "Just POST /api/projects directly"
   → Should use dss_create_project tool

❌ Tool only wraps REST endpoint
   → Tool should be primary; endpoint wraps tool

❌ Tool implementation scattered across 3 files
   → Tools should be in tools/ directory, organized

❌ New feature added to REST API but not as MCP tool
   → Every operation MUST be a tool first

❌ Tool calls not logged to audit trail
   → All tool usage must be auditable

Cross-Principle Patterns

Pattern: Adding a New Feature

1. Design the feature (Principle 1: Design is Architectural)
   ↓
2. Document in ARCHITECTURE.md with version (Principle 2: Contracts)
   ↓
3. Update Single Source of Truth (Principle 3: Single Source)
   API_CONTRACTS.md gets new endpoint spec
   ↓
4. Record why in ADR (Principle 4: Decisions Traceable)
   .knowledge/adrs/ADR-NNN.md explains rationale
   ↓
5. Create MCP Tool (Principle 5: Operations as Tools)
   dss_new_feature tool is primary
   ↓
6. REST endpoint wraps tool
   POST /api/new-feature calls tool

Timeline: Design → Docs → ADR → Tool → Endpoint

Pattern: Changing a Contract

1. Is this breaking? (Principle 2: Contracts)
   - YES → MAJOR version bump (v1.2.0 → v2.0.0)
   - NO → MINOR version bump (v1.2.0 → v1.3.0)

2. Update Single Source (Principle 3: Single Source)
   Update API_CONTRACTS.md with new version

3. Deprecate old if breaking (Principle 2: Contracts)
   Old endpoint: "Deprecated in v1.3.0, remove in v2.0.0"
   New endpoint: "Introduced in v1.3.0"

4. Record decision (Principle 4: Decisions)
   ADR: "Why did we change the contract?"

5. Update tool (Principle 5: Operations)
   Tool version must match new contract version

Timeline: Identify change → Determine version → Update docs → Update tool

Pattern: Handling Decision Conflicts

When principles conflict, use priority order:

1. Contracts are Immutable (highest)
   "This tool would break the API contract"
   → Keep contract, deprecate old tool, introduce new one

2. Single Source of Truth
   "Two files have different info"
   → Find source of truth, delete copy, add link

3. Operations as Tools
   "Tool implementation is complex"
   → Break into multiple tools, each focused

4. Decisions Traceable
   "Should we have an ADR for this?"
   → If significant and recurring, yes

5. Design is Architectural (lowest)
   "Visual tweak seems simple"
   → Still document if it affects component contracts

Enforcement & Automation

Pre-Commit Hooks

# Hook 1: Detect duplicate documentation
check-link-rot.py → Fails if same content in 2+ files

# Hook 2: Ensure version bumped
schema-diff.py → Fails if file changed but version didn't

# Hook 3: Detect phase-named files
detect-phase-names.py → Fails if *PHASE*, *DEPLOYMENT*, *WEEK* files

# Hook 4: Validate knowledge graph
knowledge-graph-validator.py → Validates .knowledge/*.json schema

CI/CD Checks

# Check 1: Version sync
version-bump-validator:
  - For any Tier 1 file change: requires version bump
  - Updates VERSIONING.md map
  - Validates semver format

# Check 2: Documentation consistency
doc-coverage:
  - Every API endpoint in code appears in API_CONTRACTS.md
  - Feature code doesn't define its own spec (references Tier 1)
  - All open bugs in code correspond to PROJECT_STATUS.md

# Check 3: Tool API alignment
tool-api-alignment:
  - Tool schema matches API_CONTRACTS.md schema
  - Tool version matches contract version
  - All tools have input/output schema

# Check 4: Link validation
link-validation:
  - All markdown links are valid
  - References to ADRs use correct format

Success Metrics

Implementation Success:

  • No duplicate documentation (use links instead)
  • All API endpoints documented once with version
  • All major decisions in .knowledge/adrs/ (with rationale)
  • No PHASE_REPORT.md, DEPLOYMENT.md in root
  • All operations have MCP tools (no REST-only endpoints)
  • Tier 1 files change only via semantic versioning
  • PROJECT_STATUS.md updated weekly (within 7 days)

Team Adoption:

  • New developer reads PRINCIPLES.md → starts coding (30 min)
  • Team asks "which principle?" before PRs
  • Developers cite principles in code reviews
  • ADRs referenced in commit messages

Organizational Value:

  • Stakeholders can check status without asking
  • Decision rationale preserved for future teams
  • Agents can work autonomously via MCP tools
  • Design changes tracked with same rigor as code

Last Updated: 2025-12-08 Version: 1.0.0 (extracted from PRINCIPLES.md) Status: PRODUCTION