# 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:
✅ RIGHT:
```
**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:**
```bash
# 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/`.
```markdown
---
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**
```bash
# 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**
```python
# 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
```bash
# 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
```yaml
# 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