ogt-docs-rules
OGT Docs - Rules
Root skill for managing project rules and standards. Rules define enforceable conventions that all contributors (human and AI) must follow.
Overview
Rules are the codified standards of a project. Unlike guidelines (suggestions) or documentation (information), rules are enforceable and verifiable. They live in docs/rules/ and are organized by domain.
flowchart TB
subgraph rules ["docs/rules/"]
direction TB
CODE["code/"]
GIT["git/"]
INFRA["infra/"]
DOCS["docs/"]
STYLE["style/"]
end
subgraph skills ["Specialized Skills"]
S1["ogt-docs-rules-code"]
S2["ogt-docs-rules-git"]
S3["ogt-docs-rules-code-front"]
S4["ogt-docs-rules-code-back"]
S5["ogt-docs-rules-code-infra"]
end
CODE --> S1
CODE --> S3
CODE --> S4
CODE --> S5
GIT --> S2
INFRA --> S5
When to Use
- Creating new project rules or standards
- Updating existing rules
- Looking up rules for a specific domain
- Enforcing rules during code review
- Setting up rules for a new project
Sub-Skills
| Skill | Domain | Use When |
|---|---|---|
ogt-docs-rules-code |
Coding standards | TypeScript, naming, patterns, error handling |
ogt-docs-rules-code-front |
Frontend code | React, components, state, styling |
ogt-docs-rules-code-back |
Backend code | API design, database, services |
ogt-docs-rules-code-infra |
Infrastructure | Docker, CI/CD, deployment |
ogt-docs-rules-git |
Git workflow | Commits, branches, PRs, reviews |
Folder Structure
docs/rules/
├── code/ # Coding standards
│ ├── general/ # Cross-cutting code rules
│ │ ├── rule.md # Primary rule definition
│ │ ├── examples.md # Good/bad examples
│ │ ├── .version # Schema version
│ │ └── .enforced_by # How it's enforced (eslint, tsc, etc.)
│ │
│ ├── typescript/ # TypeScript-specific rules
│ │ ├── rule.md
│ │ ├── examples.md
│ │ └── .enforced_by
│ │
│ ├── naming/ # Naming conventions
│ │ ├── rule.md
│ │ ├── examples.md
│ │ └── .enforced_by
│ │
│ ├── front/ # Frontend-specific rules
│ │ ├── components/
│ │ ├── state/
│ │ ├── styling/
│ │ └── routing/
│ │
│ ├── back/ # Backend-specific rules
│ │ ├── api/
│ │ ├── database/
│ │ └── services/
│ │
│ └── infra/ # Infrastructure rules
│ ├── docker/
│ ├── ci/
│ └── deployment/
│
├── git/ # Git workflow rules
│ ├── commits/ # Commit message format
│ │ ├── rule.md
│ │ ├── examples.md
│ │ └── .enforced_by
│ │
│ ├── branches/ # Branch naming
│ │ ├── rule.md
│ │ └── examples.md
│ │
│ ├── pull_requests/ # PR requirements
│ │ ├── rule.md
│ │ └── template.md
│ │
│ └── reviews/ # Code review standards
│ ├── rule.md
│ └── checklist.md
│
├── docs/ # Documentation rules
│ ├── structure/ # Folder organization
│ ├── formatting/ # Markdown standards
│ └── comments/ # Code comments
│
└── style/ # Style guides
├── ui/ # UI/UX consistency
├── api/ # API style
└── naming/ # Naming conventions
Rule Definition Structure
Every rule is a folder containing at minimum a rule.md file.
rule.md Template
# Rule: {Rule Name}
## Summary
One sentence stating the rule clearly and unambiguously.
## Rationale
Why this rule exists. What problems it prevents. What benefits it provides.
## The Rule
Clear, specific statement of what MUST, SHOULD, or MUST NOT be done.
Use RFC 2119 keywords:
- **MUST** / **REQUIRED** - Absolute requirement
- **MUST NOT** / **SHALL NOT** - Absolute prohibition
- **SHOULD** / **RECOMMENDED** - Recommended but exceptions exist
- **SHOULD NOT** - Not recommended but exceptions exist
- **MAY** / **OPTIONAL** - Truly optional
## Examples
### Correct
{Show correct usage}
### Incorrect
{Show incorrect usage with explanation}
## Exceptions
Documented cases where this rule may be relaxed.
## Enforcement
How this rule is enforced:
- Automated (linter, type checker, CI)
- Manual (code review)
- Both
## References
- Related rules
- External standards
- Tooling documentation
Example: docs/rules/code/typescript/
Complete example of a TypeScript rules folder.
Folder Structure
docs/rules/code/typescript/
├── rule.md
├── examples.md
├── .version
└── .enforced_by
rule.md
# Rule: TypeScript Strict Mode
## Summary
All TypeScript code MUST compile with strict mode enabled.
## Rationale
Strict mode catches common errors at compile time:
- Implicit any types
- Null/undefined access
- Unused variables
- Missing return types
This prevents runtime errors and improves code quality.
## The Rule
1. **MUST** enable `"strict": true` in tsconfig.json
2. **MUST NOT** use `@ts-ignore` without explanatory comment
3. **MUST NOT** use `any` type except in documented exceptions
4. **SHOULD** prefer `unknown` over `any` for unknown types
5. **MUST** fix all TypeScript errors before committing
## Examples
### Correct
```typescript
// Explicit types
function calculateTotal(items: CartItem[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
// Unknown instead of any
function parseJSON(text: string): unknown {
return JSON.parse(text);
}
// Type guards for unknown
function isUser(value: unknown): value is User {
return typeof value === "object" && value !== null && "id" in value;
}
```
Incorrect
// Implicit any - TS7006
function process(data) {
// ERROR: Parameter 'data' implicitly has 'any' type
return data.value;
}
// Using any
function handleResponse(response: any) {
// AVOID: Use unknown or specific type
return response.data;
}
// ts-ignore without comment
// @ts-ignore // BAD: No explanation
const result = brokenLibrary.call();
Exceptions
- Third-party library definitions that require
any - Migration of legacy JavaScript (with tracking issue)
- Test mocks where type safety is less critical
When using exceptions, add comment:
// Exception: Legacy API returns untyped response (see #123)
const data = legacyApi.fetch() as any;
Enforcement
- Automated:
tsc --noEmitin pre-commit hook and CI - Automated: ESLint
@typescript-eslint/no-explicit-any - Manual: Code review for exception documentation
References
- TypeScript Strict Mode
- docs/rules/code/general/ - General coding standards
### examples.md
```markdown
# TypeScript Examples
Extended examples for TypeScript rules.
## Type Inference vs Explicit Types
### When to Use Explicit Types
```typescript
// Function return types - ALWAYS explicit
function fetchUser(id: string): Promise<User> {
return api.get(`/users/${id}`);
}
// Exported constants - ALWAYS explicit
export const DEFAULT_TIMEOUT: number = 5000;
// Complex objects - ALWAYS explicit
const config: AppConfig = {
apiUrl: process.env.API_URL,
timeout: 5000,
};
When Inference is Acceptable
// Local variables with obvious types
const count = 0; // Inferred as number
const name = "test"; // Inferred as string
const items = [1, 2, 3]; // Inferred as number[]
// Arrow functions in callbacks
users.filter((user) => user.active); // Parameter type inferred from array
Union Types
Discriminated Unions
// CORRECT: Use discriminated unions
type Result<T> = { success: true; data: T } | { success: false; error: Error };
function handleResult<T>(result: Result<T>) {
if (result.success) {
console.log(result.data); // TypeScript knows data exists
} else {
console.error(result.error); // TypeScript knows error exists
}
}
Avoid Loose Unions
// INCORRECT: Loose union without discriminant
type Response = {
data?: User;
error?: Error;
};
// Problem: Both could be undefined, or both could be set
Generic Constraints
// CORRECT: Constrain generics appropriately
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// INCORRECT: Unconstrained generic
function getValue<T>(obj: T, key: string): any {
// Returns any!
return (obj as any)[key];
}
### .version
```json
{ "schema": "1.0", "created": "2026-01-15T10:00:00Z", "updated": "2026-02-01T14:00:00Z" }
.enforced_by
tsc --noEmit
eslint --ext .ts,.tsx
pre-commit hook
CI pipeline
Example: docs/rules/git/commits/
Complete example of commit message rules.
Folder Structure
docs/rules/git/commits/
├── rule.md
├── examples.md
├── .version
└── .enforced_by
rule.md
# Rule: Commit Message Format
## Summary
All commit messages MUST follow Conventional Commits format.
## Rationale
Consistent commit messages enable:
- Automated changelog generation
- Semantic versioning automation
- Easy history navigation
- Clear communication of changes
## The Rule
### Format
():
[optional body]
[optional footer(s)]
### Types
| Type | Use When |
|------|----------|
| `feat` | New feature |
| `fix` | Bug fix |
| `docs` | Documentation only |
| `style` | Formatting, no code change |
| `refactor` | Code change that neither fixes nor adds |
| `perf` | Performance improvement |
| `test` | Adding/updating tests |
| `chore` | Maintenance tasks |
| `ci` | CI/CD changes |
### Requirements
1. **MUST** use lowercase type
2. **MUST** use imperative mood in description ("add" not "added")
3. **MUST** limit first line to 72 characters
4. **SHOULD** include scope for clarity
5. **MUST** reference issue number in footer for bug fixes
6. **MUST** mark breaking changes with `!` or `BREAKING CHANGE:` footer
## Examples
### Correct
feat(auth): add Steam OAuth provider
Implement Steam OpenID authentication flow. Follows existing Google/Discord pattern.
Closes #456
fix(api): handle null response from legacy endpoint
The /v0/users endpoint can return null for deleted users. Add null check and return 404 instead of 500.
Fixes #789
refactor(components): extract CardBase from entity cards
DRY refactor - all entity cards now extend CardBase. No functional changes.
feat(api)!: change authentication header format
BREAKING CHANGE: Authorization header now requires "Bearer " prefix. Migration guide: docs/guides/auth_migration.md
### Incorrect
Fixed bug // No type, no scope, vague
FEAT: Add new feature // Wrong case
feat(auth): Added Steam OAuth // Past tense
feat: implement the new user authentication system with Steam support and update all related components // Too long
## Exceptions
- Merge commits may use default message
- Revert commits may use git's default format
## Enforcement
- **Automated**: commitlint in pre-commit hook
- **Automated**: CI check on PR
- **Manual**: PR review
## References
- [Conventional Commits](https://www.conventionalcommits.org/)
- [Angular Commit Guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit)
examples.md
# Commit Message Examples
## Feature Commits
feat(creatures): add CR filtering to creature list
Allow filtering creatures by Challenge Rating range. Uses dual-handle slider component.
Related: #234
feat(search): implement fuzzy search with MiniSearch
Replace substring matching with indexed fuzzy search. Results ranked by relevance score.
Performance: <16ms for 10k entries
Closes #567
## Bug Fix Commits
fix(cards): prevent image flash on card hover
Card images were reloading on every hover due to missing key prop in map. Add stable key based on entity slug.
Fixes #890
fix(auth): handle expired refresh tokens gracefully
When refresh token expires, redirect to login instead of showing error page. Clear local storage on redirect.
Fixes #891 Fixes #892
## Refactor Commits
refactor(services): extract API client from services
Move HTTP logic to dedicated ApiClient class. Services now use dependency injection.
No functional changes. Improves testability.
## Documentation Commits
docs(readme): add Docker setup instructions
Document docker-compose workflow for new developers. Include troubleshooting section for common issues.
## Breaking Change Commits
feat(api)!: rename /monsters to /creatures
BREAKING CHANGE: All /api/monsters/_ endpoints now at /api/creatures/_
Migration:
- Update all fetch calls
- /monsters/:slug -> /creatures/:slug
- Search params unchanged
Deprecation notice sent 2026-01-01. Old endpoints removed 2026-02-01.
.enforced_by
commitlint
husky pre-commit
GitHub Actions CI
Creating New Rules
flowchart TD
A[Identify Need for Rule] --> B{Rule Type?}
B -->|Code| C[docs/rules/code/]
B -->|Git| D[docs/rules/git/]
B -->|Docs| E[docs/rules/docs/]
B -->|Style| F[docs/rules/style/]
C --> G[Create Rule Folder]
D --> G
E --> G
F --> G
G --> H[Write rule.md]
H --> I[Add examples.md]
I --> J[Set .version]
J --> K[Document .enforced_by]
K --> L{Automated Enforcement?}
L -->|Yes| M[Configure Tooling]
L -->|No| N[Add to Review Checklist]
M --> O[Add to CI]
N --> O
O --> P[Announce to Team]
Steps
- Choose domain: code/, git/, docs/, style/
- Create folder:
docs/rules/{domain}/{rule_name}/ - Write rule.md: Use template above
- Add examples.md: Comprehensive good/bad examples
- Create .version: Schema versioning
- Document .enforced_by: List enforcement mechanisms
- Configure automation: ESLint rules, commit hooks, CI checks
- Announce: Communicate new rule to team
Signal Files Reference
| Signal | Type | Content | Purpose |
|---|---|---|---|
.version |
Content | JSON with schema, created, updated | Track rule version |
.enforced_by |
Content | List of tools/processes | Document enforcement |
.deprecated |
Empty | - | Mark rule as deprecated |
.superseded_by |
Content | Path to new rule | Point to replacement |
.approved_by_{name} |
Empty | - | Track approval |
Rule Quality Checklist
Before finalizing a rule:
- Summary is one clear sentence
- Rationale explains WHY (not just what)
- Uses RFC 2119 keywords correctly
- Has at least 2 correct examples
- Has at least 2 incorrect examples with explanations
- Exceptions are documented
- Enforcement mechanism is specified
- Examples compile/work if code
- No ambiguity in requirements
- Cross-referenced with related rules
More from opendndapps/ogt-skills
ogt-docs-changelog
Manage project changelog following Keep a Changelog format. Use when documenting releases, adding change entries, generating changelogs from commits, or maintaining version history.
10ogt-docs-define-tools
Document project tools and CLI utilities in docs/define/tools/. Use when documenting internal CLIs, scripts, development tools, or third-party integrations that team members need to understand and use.
9ogt-cli-claude
Run Claude Code CLI for complex tasks, code generation, analysis, and research. Uses Anthropic OAuth (included in Claude Pro). Use for extended thinking, code review, architecture decisions. Preferred for load balancing sub-agent work (35% weight).
8jq
Command-line JSON processor. Extract, filter, transform JSON.
8ogt-docs-define-branding
Create brand definition documents covering visual identity, tone of voice, brand guidelines, and brand assets. Use when establishing or documenting brand identity and ensuring consistent brand expression.
8ogt-agent-team
Spawn a Team Leader agent that manages multiple sub-agents working toward a common goal. Team Leader reads requirements, decomposes work, assigns personalities and tasks, manages communication between team members, tracks progress, and reports results following ogt-docs task workflow. Integrates fully with docs-first system via task signals and status tracking.
8