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