
Last episode answered “which layer do external contributions land on” — five role PRs, zero core PRs. This episode answers a single question: why did the role layer become a low-risk contribution surface?
Not because “the docs were good” — CONTRIBUTING.md only has a brief section about roles. Not because “roles are simple” — role definitions involve review perspectives, expertise domains, activation conditions, and anti-patterns, none of which are trivial. The real reason lies in the signals the interface itself emits.
Three Signals
For an interface to make strangers willing to modify it, it must simultaneously emit three signals:
Signal 1: Understandable. Outsiders can grasp the format and semantics without guidance.
Signal 2: Modifiable. Outsiders can make changes using existing tools, without setting up an environment or understanding the call chain.
Signal 3: Safe to break. The worst-case consequence of getting it wrong is acceptable.
These three signals aren’t independent — they form a progression. Understandable but not modifiable is useless. Modifiable but dangerous to break means nobody dares. All three must be satisfied simultaneously for actual contributions to happen.
Signal 1: Understandable — Self-Explaining Structure
Open any roles/*.md file:
---
name: performance
title: Performance Specialist
tags: [review]
---
## Identity
You are a performance-focused code reviewer...
## Expertise
- Algorithmic complexity analysis
- Memory allocation patterns
...
## When to Include
- Code touching hot paths or data-intensive loops
...
## Anti-Patterns
- Premature optimization without profiling evidence
...
Several characteristics make this format self-explaining:
The naming is semantic. Identity needs no explanation — it’s “who you are.” Expertise is “what you’re good at.” When to Include is “when should you be called in.” Anti-Patterns is “when not to do something.” The four section names are their own complete documentation.
Examples are the spec. When you see roles/frontend.md’s ## Identity reads “You are a frontend specialist…”, you don’t need any spec to know your own ## Identity should also start with “You are a…”. Existing role files are the best template. S1E04 noted that “existing code is documentation” — in the role system, existing roles are the specification.
YAML frontmatter is self-evident. name: performance, title: Performance Specialist, tags: [review] — you don’t need to know which code parses tags; seeing the contrast between [review] and [build] tells you it’s a classification label.
PR #24’s description states: “Based on the role template in CONTRIBUTING.md.” But CONTRIBUTING.md has only three lines about roles. The real template was roles/frontend.md itself — the contributor opened an existing file, understood the structure, and copy-pasted it into their own version.
Compare the harness core. flow-transition.mjs has a function handling node transitions:
function resolveNextNode(currentNode, verdict, loopCounts, maxLoops) {
const edges = FLOW_GRAPHS[currentFlow].edges[currentNode];
// ...
}
To understand this code, you need to know: What’s the data structure of FLOW_GRAPHS? What fields does each element in edges have? How many possible values does verdict have? How is loopCounts incremented? A single function signature implies the entire pipeline’s state model.
Understanding cost of a role file is O(1) — open one file and you’re done. Understanding cost of core code is O(n) — you need to understand n interdependent components before you can change one.
Signal 2: Modifiable — Zero Toolchain Dependency
What do you need to modify a role file?
- A text editor
- Markdown literacy
- Domain knowledge in some specialty area
No npm install. No understanding OPC’s build system. No running tests (role files don’t have corresponding tests). No configuring a local development environment. No knowing that flow-transition.mjs exists.
The contribution path looks like this:
Fork → Create roles/xxx.md in GitHub's web editor → Paste four-section template → Fill in content → Submit PR
The entire process can be completed in a browser without cloning the repository locally.
Compare the core code contribution path:
Fork → Clone → npm install → Understand flow-transition.mjs →
Understand gate-protocol.md → Understand synthesize's emoji parsing logic →
Write code → Run 109 tests → Verify no existing flows break → Submit PR
The first path has near-zero friction. The second path is a wall.
Cherry Studio (an Electron desktop app) shows a similar layered phenomenon. Its plugin system has two tiers: providers/ AI model adapters only need to implement a standard interface (sendMessage, getModels), and the community contributed 20+ providers; but the core conversation management, context window calculation, and session storage — zero external PRs. Providers are the “modifiable” interface; the core is the wall.
Signal 3: Safe to Break — Maximum Degradation Scope
This is the most important signal.
What happens when a role file is wrong?
Best case: The review pipeline gains an effective new perspective. The Performance role helps reviewers spot a hidden O(n²).
Worst case: The review pipeline gains an ineffective perspective. Some role’s ## Expertise is too broad, producing noisy suggestions during review. OPC’s gate system won’t crash because one role’s suggestion quality is poor — synthesize judges by emoji count, and one role’s noise won’t change the overall verdict.
Recovery cost of worst case: Delete or modify one markdown file. Ten seconds.
Now look at core code. What happens when a decision condition in gate-protocol.md is wrong?
Worst case: All gate decisions invert. What should PASS becomes FAIL; what should FAIL becomes PASS. S2E08’s discovery of “FAIL never fired” could become “PASS never fires.” The entire pipeline’s behavior flips.
Recovery cost of worst case: Requires understanding the gate state machine, emoji parsing logic, and loop counter interactions, locating the error, and rolling back to the correct version. Could take hours.
Expressed as a formula:
Contribution willingness ∝ 1 / (max degradation scope × recovery cost)
Role files: low maximum degradation, near-zero recovery cost. High contribution willingness.
Core code: high maximum degradation, high recovery cost. Contribution willingness approaches zero — unless you truly understand the system.
Where the Three Signals Converge
Looking at all three signals together:
| Dimension | Role Files | Core Code |
|---|---|---|
| Understandable | O(1), open one file | O(n), understand n components |
| Modifiable | Can edit in browser | Needs full local environment |
| Safe to break | Worst: one noisy perspective | Worst: pipeline behavior flips |
| Actual contributions | 5 PRs | 0 PRs |
This table isn’t credit to deliberate role system design — honestly, these characteristics are more coincidence than intention. Role files use markdown because Claude Code’s skill system uses markdown. The four-section structure emerged because I needed a simple role definition format in S1E04 and happened to pick self-explaining names. CONTRIBUTING.md’s mention of role contributions was added later, not designed as an entry point.
But the effect of that coincidence is real. Good extension points aren’t always designed — sometimes you pick a simple format that happens to satisfy all three signals.
Low-Risk Contribution Surface: The Entry Point for Trust Transfer
EP01 said trust has five layers. EP02 said trust transferred at the leaf layer but stopped at the core layer. This episode adds the mechanism in between:
Low-Risk Contribution Surface is the entry point for trust transfer.
When an open-source project wants external contributions, the first step isn’t writing better documentation, simplifying code, or labeling “good first issues.” The first step is ensuring there exists an interface layer that simultaneously satisfies “understandable, modifiable, and safe to break.”
OPC’s role system happens to be such an interface layer. It’s not the most important part — the core is harness and gate. But it’s the part most likely to generate external contributions. Trust doesn’t start from the core — trust starts from the safest interface.
LangChain’s core abstraction layer has 67,700 lines of code (S2E04 data), but its most active external contributions aren’t in the core — they’re in the integrations/ directory’s third-party tool adapters. LobeHub has over 400 community-contributed AI model providers, but changes to the core agent runtime come almost entirely from the internal team.
The pattern is consistent: external trust starts from the leaves; core trust requires deeper understanding to earn.
Not All Leaves Are Good Contribution Surfaces
A counterexample.
OPC’s pipeline/ directory contains protocol files — gate-protocol.md, loop-protocol.md, report-format.md. These are also markdown files with fixed structures. But they’re not good contribution surfaces:
Understandable? Partially. You can read each paragraph, but you don’t know how modifying a threshold affects gate decisions.
Modifiable? Yes. Modifying markdown requires no toolchain.
Safe to break? No. Changing the severity mapping rules in gate-protocol.md affects all gate decisions. Maximum degradation scope equals that of core code.
Same markdown format, but roles/*.md is a good contribution surface while pipeline/*.md isn’t. File format doesn’t determine contribution threshold — degradation scope determines contribution threshold.
Design Implications: How to Create Low-Risk Contribution Surfaces
A few actionable principles distilled from the role system experience:
1. Make the format self-explaining. Four-section naming needs no comments — Identity, Expertise, When to Include, Anti-Patterns are their own documentation. If your interface needs a page of docs to explain usage, it’s not self-explaining enough.
2. Let existing instances serve as templates. Don’t write a spec; write one good example file. Contributors will copy-paste and modify, not read specs from scratch. OPC has roles/frontend.md as a template; #24’s Performance role was copied from it.
3. Isolate degradation scope. One role file going wrong doesn’t affect other roles, doesn’t affect gates, doesn’t affect pipeline routing. This isolation isn’t accidental — each role is an independent markdown file, not a section in one large config file. If all roles were defined in a single roles.yaml, a format error in one role could cause the entire file to fail parsing. One file per role is the simplest method for isolating degradation scope.
4. Make recovery cost visible. When contributors know “the worst case is just deleting the file I added,” the psychological burden is minimal. CONTRIBUTING.md could explicitly state: what’s the risk of changing a role file, what’s the risk of changing core code. Let contributors choose their own risk level.
Next episode looks at the same question from the opposite side: why did nobody touch the core? Not just because the core’s degradation scope is high — but because the core’s “you can change this” invitation was never issued.
Silicon Team S3: From “I Can Use It” to “Others Can Use It” ← S3E02: They Add Roles, But Won’t Touch the Core | S3E04: Nobody Touched the Gate — The Core Isn’t a Public Asset Yet →