A Claude skill for agents developing organon-tools — ensures the tools that enforce methodology are built using methodology.
When to Use This Skill
Use this skill when:
- Adding a new CLI command (
organon <command>)
- Adding a new verification gate
- Adding a new MCP tool/prompt/resource
- Evolving the methodology specification (book-llms/)
- Fixing bugs or refactoring organon-tools code
Purpose: Ensure organon-tools development follows its own ETHOS.md constraints and PHILOSOPHY.md design decisions.
Identity Check (Always Start Here)
Before any work, load and internalize:
- Read
organon/domains/tools/ETHOS.md - 6 invariants, 5 principles, 8 heuristics
- Read
organon/domains/tools/PHILOSOPHY.md - 5 design decisions and trade-offs
- Read
book-llms/three-layer-architecture.md - If working on verification gates
Critical constraint: This tool builds tools that enforce methodology. The builder must follow what it builds.
The 6 Invariants (Never Violate)
From organon/domains/tools/ETHOS.md:
- Schema fidelity - Frontmatter parser matches
book-llms/frontmatter-system.md exactly
- Every command has tests - No untested code ships
- Gates fail builds, not warn - Verification gates produce pass/fail, never soft warnings
- Machine-parsable output - All commands support
--format json
- Idempotent operations - Same input = same output, no side effects
- Breaking changes require major version bump - CLI, JSON schema, frontmatter schema
If your change violates any invariant, STOP and redesign.
The 5 Design Principles (Prioritized)
From organon/domains/tools/ETHOS.md:
- Schema fidelity over convenience - When book-llms/ spec conflicts with ease-of-use, spec wins
- Fail-fast over forgiving - Invalid input blocks execution, errors surface immediately
- Composability over monoliths - Commands work in Unix pipelines
- Testability over implementation speed - Pure functions with tests, thin CLI wrappers
- Clarity over brevity - Error messages explain what failed and how to fix it
Core Architecture Pattern
From organon/domains/tools/PHILOSOPHY.md:
src/
├── core/ ← Pure functions (no I/O, no console, no process.exit)
│ ├── types.ts ← FileSystem interface, result types
│ ├── <feature>.ts ← Pure logic with tests
│ └── <feature>.test.ts ← Vitest tests (>90% coverage)
├── cli/commands/ ← Thin wrappers (yargs handlers)
│ └── <command>.ts ← Parse args → call core → format output
└── mcp/ ← Thin MCP adapters
├── tools.ts ← Wrap core functions as MCP tools
└── prompts.ts ← Methodology workflow templates
Pattern: Core logic is pure and testable. CLI and MCP are thin adapters.
Workflow 1: Adding a New CLI Command
Example: Adding organon check-links command
-
Design phase (before coding):
-
Implementation phase:
bash
1# Create core utility (pure function)
2touch src/core/check-links.ts
3touch src/core/check-links.test.ts
4
5# Create CLI command wrapper
6touch src/cli/commands/check-links.ts
-
Core utility structure (src/core/check-links.ts):
typescript
1import { FileSystem, Result } from './types';
2
3export interface CheckLinksOptions {
4 projectRoot: string;
5 // ... other options
6}
7
8export interface CheckLinksResult {
9 success: boolean;
10 brokenLinks: Array<{ file: string; link: string; reason: string }>;
11}
12
13export async function checkLinks(
14 options: CheckLinksOptions,
15 fs: FileSystem
16): Promise<CheckLinksResult> {
17 // Pure logic here - no console.log, no process.exit
18 // Return structured results
19}
-
Write tests first (src/core/check-links.test.ts):
typescript
1import { describe, it, expect } from 'vitest';
2import { checkLinks } from './check-links';
3import { MockFileSystem } from './test-utils';
4
5describe('checkLinks', () => {
6 it('detects broken links', async () => {
7 const fs = new MockFileSystem({ ... });
8 const result = await checkLinks({ projectRoot: '.' }, fs);
9 expect(result.brokenLinks).toHaveLength(1);
10 });
11
12 // ... more tests
13});
-
CLI wrapper (src/cli/commands/check-links.ts):
typescript
1import yargs from 'yargs';
2import { checkLinks } from '../../core/check-links';
3import { NodeFileSystem } from '../../core/node-fs';
4
5export const checkLinksCommand: yargs.CommandModule = {
6 command: 'check-links',
7 describe: 'Check for broken links in organon files',
8 builder: (yargs) => {
9 return yargs
10 .option('format', {
11 choices: ['human', 'json'] as const,
12 default: 'human' as const,
13 });
14 },
15 handler: async (args) => {
16 const fs = new NodeFileSystem();
17 const result = await checkLinks({ projectRoot: process.cwd() }, fs);
18
19 if (args.format === 'json') {
20 console.log(JSON.stringify(result, null, 2));
21 } else {
22 // Human-readable output
23 if (result.brokenLinks.length === 0) {
24 console.log('✓ No broken links found');
25 } else {
26 console.error('✗ Found broken links:');
27 result.brokenLinks.forEach(l => {
28 console.error(` ${l.file}: ${l.link} (${l.reason})`);
29 });
30 }
31 }
32
33 process.exit(result.success ? 0 : 1);
34 },
35};
-
Register command (in src/cli/index.ts):
typescript
1import { checkLinksCommand } from './commands/check-links';
2
3yargs
4 .command(checkLinksCommand)
5 // ... other commands
-
Verification checklist:
Workflow 2: Adding a New Verification Gate
Example: Adding a "freshness" gate that checks last-modified dates
-
Update specification first:
-
Implementation (follow Workflow 1 pattern):
bash
1# Core logic
2touch src/core/verify-freshness.ts
3touch src/core/verify-freshness.test.ts
-
Gate structure (src/core/verify-freshness.ts):
typescript
1import { FileSystem, VerificationResult } from './types';
2
3export async function verifyFreshness(
4 projectRoot: string,
5 fs: FileSystem
6): Promise<VerificationResult> {
7 return {
8 gate: 'freshness',
9 passed: boolean,
10 errors: Array<{ file: string; message: string; fix: string }>,
11 warnings: [], // Gates never warn, only fail
12 };
13}
-
Register gate (in src/core/verify.ts):
typescript
1import { verifyFreshness } from './verify-freshness';
2
3const GATES = {
4 'freshness': verifyFreshness,
5 // ... other gates
6};
-
Test coverage requirements:
-
Update CLI (src/cli/commands/verify.ts):
typescript
1.option('gate', {
2 type: 'array',
3 choices: ['frontmatter', 'references', 'triplets', 'coverage', 'freshness'],
4 description: 'Run specific gates (defaults to all)',
5})
-
Verification checklist:
Example: Adding organon_check_dependencies MCP tool
-
Core function exists (or create it following Workflow 1)
-
Add MCP tool (src/mcp/tools.ts):
typescript
1{
2 name: 'organon_check_dependencies',
3 description: 'Check if organon file dependencies are satisfied',
4 inputSchema: {
5 type: 'object',
6 properties: {
7 file: { type: 'string', description: 'Path to organon file' },
8 },
9 required: ['file'],
10 },
11 handler: async (args) => {
12 const result = await checkDependencies(args.file, fs);
13 return {
14 content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
15 };
16 },
17}
-
Add MCP prompt (src/mcp/prompts.ts) - If it's a workflow:
typescript
1{
2 name: 'check-organon-dependencies',
3 description: 'Workflow for verifying organon dependency chains',
4 arguments: [
5 { name: 'scope', description: 'Scope to check (product, domain, feature)', required: false },
6 ],
7 handler: async (args) => {
8 return {
9 messages: [
10 {
11 role: 'user',
12 content: {
13 type: 'text',
14 text: `# Check Organon Dependencies Workflow\n\n...`,
15 },
16 },
17 ],
18 };
19 },
20}
-
Verification checklist:
Workflow 4: Evolving the Methodology (RFC-Aware)
Example: Adding a new frontmatter field
DANGER ZONE: Changes to book-llms/ affect ALL projects using Organon.
-
RFC pattern (from book-llms/patterns.md):
-
Breaking change checklist (requires major version bump):
-
Invariant check:
- Schema fidelity: Implementation must match spec exactly
- Breaking changes require major version bump: Semver enforced
Common Pitfalls (Don't Do This)
- ❌ Adding logic to CLI commands → ✅ Add to
src/core/, CLI is thin wrapper
- ❌ Using
console.log in core functions → ✅ Return structured results, CLI formats
- ❌ Using
process.exit in core functions → ✅ Return success/failure, CLI exits
- ❌ Writing tests after code → ✅ Write tests first (TDD pattern)
- ❌ Making gates warn instead of fail → ✅ Gates fail builds (INV-TOOLS-3)
- ❌ Skipping
--format json support → ✅ All commands must support it (INV-TOOLS-4)
- ❌ Implementing before spec updated → ✅ Update book-llms/ spec first
- ❌ Auto-fixing invalid frontmatter → ✅ Fail-fast, force user to fix (principle #2)
Pre-Commit Verification
Before committing ANY code:
bash
1# 1. Tests pass
2npm test
3
4# 2. No TypeScript errors
5npm run build
6
7# 3. Self-verification (dogfooding)
8npm run organon verify
9
10# 4. Coverage check (>90% for core, 100% for gates)
11npm run test:coverage
If any fail, do not commit.
When in Doubt
- Check ETHOS.md - Does this violate an invariant?
- Check PHILOSOPHY.md - Does this align with design decisions?
- Check three-layer-architecture.md - Is this the right pattern for gates?
- Ask: Would this tool enforce what I'm about to build?
Remember: Organon-tools builds tools that enforce methodology. If you wouldn't want the tool to allow this pattern, don't implement it.
The tools that enforce constraints must be built with more discipline than the code they govern.
If organon-tools has untested code, how can it enforce test coverage on others?
If organon-tools has invalid frontmatter, how can it validate others?
If organon-tools violates its own ETHOS.md, the methodology loses credibility.
Build the tools you wish existed when auditing someone else's work.
Error Recovery
| Failure | Recovery Action |
|---|
| Tests fail | Fix implementation to match test expectations. Do not skip or disable tests. |
| Coverage below threshold (>90% core, 100% gates) | Add missing test cases for uncovered branches. Use npm run test:coverage to identify gaps. |
| TypeScript compilation errors | Fix type issues. Do not use any or @ts-ignore as workarounds. |
| Gate warns instead of failing | Change gate to produce pass/fail exit codes. Invariant INV-TOOLS-3: gates fail builds, never warn. |
--format json not supported | Add JSON output format. Invariant INV-TOOLS-4: all commands must support --format json. |
| Breaking change detected | Bump major version. Invariant INV-TOOLS-6: breaking changes require major version bump. |
| Spec not updated before implementation | Stop. Update book-llms/ specification first, then implement to match. Spec is source of truth. |