# How to Establish Skill-to-Skill Relationships in Zettelkasten for cangjie-skill: A Practical Guide

> Master skill to skill relationships in Zettelkasten for cangjie skill using depends on contrasts with and composes with. Build a navigable knowledge graph easily.

- Repository: [kangarooking/cangjie-skill](https://github.com/kangarooking/cangjie-skill)
- Tags: best-practices
- Published: 2026-08-15

---

**Use three relationship types—`depends-on`, `contrasts-with`, and `composes-with`—encoded in YAML front-matter and natural-language sections to transform isolated skills into a navigable knowledge graph.**

The **cangjie-skill** repository implements a Zettelkasten-style knowledge management system where each skill stands as an atomic markdown file ([`SKILL.md`](https://github.com/kangarooking/cangjie-skill/blob/main/SKILL.md)). Establishing skill-to-skill relationships is the critical stage that turns a flat collection into a functioning network of connected ideas. This article covers the methodology defined in [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md), including relationship types, front-matter syntax, and quality guidelines proven in the project's workflow.

## The Three Core Relationship Types

The cangjie-skill system deliberately limits relationships to three semantic categories. This constraint prevents graph complexity from exploding while preserving expressive power.

| Relation | Meaning | Example from the codebase |
|----------|---------|---------------------------|
| **depends-on** | Prerequisite knowledge—Skill A requires Skill B | "检查清单决策" depends-on "多元思维模型" |
| **contrasts-with** | Alternative approaches for contextual selection | "正向推理" contrasts-with "逆向思维" |
| **composes-with** | Frequently paired skills used together | "能力圈判断" composes-with "安全边际" |

These definitions appear in [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md) at lines 9-16. The sparse type system ensures automated tools can reason about the graph without natural-language parsing.

## Front-Matter Syntax for Related Skills

Each [`SKILL.md`](https://github.com/kangarooking/cangjie-skill/blob/main/SKILL.md) file declares relationships in YAML front-matter under the `related_skills` key. The structure requires two fields per entry: `slug` (the target skill's identifier) and `relation` (one of the three types).

```yaml
---
slug: forward-reasoning
title: 正向推理
related_skills:
  - slug: reverse-thinking
    relation: contrasts-with
  - slug: mental-models
    relation: depends-on
  - slug: circle-of-competence
    relation: composes-with
---

```

This machine-readable format enables programmatic traversal. Tools can generate recommendation graphs, visualize dependency chains, or validate that no orphaned skills exist in a book collection.

## Human-Readable Relationship Documentation

Every skill file must include a trailing "Related Skills" section that translates the YAML into natural language. This serves readers who browse the repository directly without parsing front-matter.

```markdown

## Related Skills

- **Contrasts-with**: *逆向思维* – while forward reasoning builds conclusions 
  from premises, reverse thinking works backwards from desired outcomes.
- **Depends-on**: *多元思维模型* – effective forward reasoning requires a solid 
  mental-model foundation.
- **Composes-with**: *能力圈判断* – forward reasoning and circle-of-competence 
  assessment combine when evaluating investment opportunities.

```

The dual encoding—YAML for machines, prose for humans—ensures the Zettelkasten remains accessible during both automated processing and manual exploration.

## Six-Step Workflow for Adding Relationships

The cangjie-skill methodology prescribes a systematic workflow defined in [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md) (lines 22-33):

1. **Gather skills** produced in stage 2 (the "parallel extract" step).
2. **Pairwise scan** the complete list, identifying any of the three relationship types.
3. **Edit front-matter** in each [`SKILL.md`](https://github.com/kangarooking/cangjie-skill/blob/main/SKILL.md) to populate `related_skills` with `slug` and `relation` entries.
4. **Append "Related Skills" section** with natural-language descriptions for each connection.
5. **Back-fill the A2 paragraph** (the "distinction from neighboring skills" draft) with finalized descriptions.
6. **Generate [`INDEX.md`](https://github.com/kangarooking/cangjie-skill/blob/main/INDEX.md)** using `templates/INDEX.md.template` to create per-book navigation.

This sequence ensures relationships are established before index generation, so navigation pages reflect the complete graph structure.

## Quality Guidelines: Keeping the Graph Healthy

The methodology enforces two principles at lines 44-47 to maintain graph integrity:

- **No fabricated links** – Only add relationships when genuine semantic connections exist. Resist the urge to connect everything.
- **Target density of 8-15 relationships per ~10 skills** – Fewer than 5 suggests over-segmentation; more than 25 indicates forced connections that will confuse readers.

These thresholds emerged from practical testing in the cangjie-skill knowledge base. Sparse, meaningful graphs outperform dense, arbitrary ones for learning and navigation.

## Automating Index Generation

The `related_skills` front-matter enables automated tooling. Below is a simplified Python script that loads skill files and generates per-book indexes:

```python
import yaml
import pathlib

def load_skill(slug: str) -> dict:
    """Extract YAML front-matter from a SKILL.md file."""
    path = pathlib.Path(f'books/{slug}/SKILL.md')
    text = path.read_text()
    # Split on '---' to isolate front-matter

    front_matter = text.split('---')[1]
    return yaml.safe_load(front_matter)

def build_index(book_slug: str, skill_slugs: list[str]) -> None:
    """Generate INDEX.md for a book from its constituent skills."""
    entries = []
    for slug in skill_slugs:
        front = load_skill(slug)
        title = front['title']
        entries.append(f"- [{title}]({slug}/SKILL.md)")
    
    index_content = f"""# {book_slug} – Index

## Skills

{'\n'.join(entries)}
"""
    output_path = pathlib.Path(f'books/{book_slug}/INDEX.md')
    output_path.write_text(index_content)

```

This script mirrors the generation logic referenced in [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md) at lines 32-33, using `templates/INDEX.md.template` as a base.

## Key Files in the Relationship System

| File | Purpose |
|------|---------|
| [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md) | Canonical definition of relationship types, workflow, and quality guidelines |
| `templates/SKILL.md.template` | Boilerplate ensuring `related_skills` field exists in new skills |
| `templates/INDEX.md.template` | Template for per-book navigation indexes |
| [`SKILL.md`](https://github.com/kangarooking/cangjie-skill/blob/main/SKILL.md) (per skill) | Stores front-matter relationships and human-readable descriptions |
| [`INDEX.md`](https://github.com/kangarooking/cangjie-skill/blob/main/INDEX.md) (per book) | Auto-generated navigation using the relationship graph |

## Summary

- **Three relationship types**—`depends-on`, `contrasts-with`, `composes-with`—capture all necessary semantic connections without over-complicating the graph.
- **Dual encoding** in YAML front-matter and natural-language sections serves both automated tools and human readers.
- **Six-step workflow** ensures systematic relationship establishment before index generation.
- **Density guidelines** (8-15 relationships per ~10 skills) prevent under-connected or over-connected graphs.
- **Programmatic traversal** via `related_skills` enables recommendation engines, visualizations, and validation tools.

## Frequently Asked Questions

### What makes cangjie-skill's relationship model different from standard Zettelkasten linking?

Traditional Zettelkasten uses free-form bidirectional links. The cangjie-skill system constrains relationships to three typed categories with explicit directionality, making the graph machine-parseable for automated recommendations while preserving human readability through dual encoding.

### Can I add custom relationship types beyond the three defined?

The methodology explicitly discourages this. Lines 44-46 of [`methodology/05-stage3-zettelkasten.md`](https://github.com/kangarooking/cangjie-skill/blob/main/methodology/05-stage3-zettelkasten.md) emphasize standardized types to maintain tool compatibility and cognitive simplicity. Custom types would break the [`INDEX.md`](https://github.com/kangarooking/cangjie-skill/blob/main/INDEX.md) generation templates and complicate graph algorithms.

### How do I handle a skill with no clear relationships to others?

Leave `related_skills` empty and omit the "Related Skills" section. The quality guidelines suggest this indicates possible over-segmentation—consider whether the skill should merge with a related concept or if the book scope needs adjustment.

### Is the YAML front-matter required for the system to function?

Yes. The [`INDEX.md`](https://github.com/kangarooking/cangjie-skill/blob/main/INDEX.md) generation and any validation tooling depend on parsing `related_skills` programmatically. The natural-language section alone is insufficient for automated processing, though it improves human navigation.