📦 deps(skills): sync thirdparty skills
This commit is contained in:
@@ -1 +0,0 @@
|
||||
karpathy-guidelines
|
||||
@@ -0,0 +1 @@
|
||||
cangjie-skill
|
||||
@@ -1 +0,0 @@
|
||||
codebase-migrate
|
||||
@@ -1,2 +1 @@
|
||||
codebase-recon
|
||||
pathfinding
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
darwin-skill
|
||||
@@ -1,29 +1,19 @@
|
||||
ask-matt
|
||||
code-review
|
||||
codebase-design
|
||||
diagnosing-bugs
|
||||
domain-modeling
|
||||
git-guardrails-claude-code
|
||||
grill-me
|
||||
grill-with-docs
|
||||
grilling
|
||||
handoff
|
||||
implement
|
||||
improve-codebase-architecture
|
||||
migrate-to-shoehorn
|
||||
prototype
|
||||
research
|
||||
resolving-merge-conflicts
|
||||
scaffold-exercises
|
||||
setup-matt-pocock-skills
|
||||
setup-pre-commit
|
||||
tdd
|
||||
teach
|
||||
to-questionnaire
|
||||
to-spec
|
||||
to-tickets
|
||||
triage
|
||||
wait-what
|
||||
wayfinder
|
||||
wizard
|
||||
writing-for-agents
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
uncle-bob-craft
|
||||
Vendored
+19
-10
@@ -55,6 +55,11 @@ maturity stages. One of:
|
||||
|
||||
See **Health Score Calculation** below for the per-preset deduction weights.
|
||||
|
||||
**`sweep`** — Full Sweep only. `max_iterations` (default 3) caps how many
|
||||
non-critical re-scan rounds the sweep pipeline runs before it stops and reports
|
||||
the remainder as unresolved. Critical findings are exempt from the cap — they
|
||||
iterate until resolved or retired. Ignored by every other mode.
|
||||
|
||||
**Minimal example:**
|
||||
```yaml
|
||||
version: 1
|
||||
@@ -65,6 +70,8 @@ severity:
|
||||
R1: suggestion
|
||||
ignore:
|
||||
- "**/*.generated.*"
|
||||
sweep:
|
||||
max_iterations: 3
|
||||
```
|
||||
|
||||
If `.brooks-lint.yaml` contains a `custom_risks` map, read `custom-risks-guide.md`
|
||||
@@ -109,10 +116,9 @@ When no files or code are specified, detect scope automatically:
|
||||
|
||||
## The Six Decay Risks
|
||||
|
||||
Navigation index only — canonical definitions (symptoms, severity guides, sources, "What Not
|
||||
to Flag" guards) live in `decay-risks.md`. Do not duplicate or edit diagnostic questions here;
|
||||
update `decay-risks.md` directly. Book-level coverage, exceptions, and tradeoffs are in
|
||||
`source-coverage.md`.
|
||||
Navigation index only. Canonical definitions — symptoms, severity guides, sources, "What Not
|
||||
to Flag" guards — live in `decay-risks.md`; edit them there, not here. Book-level coverage,
|
||||
exceptions, and tradeoffs are in `source-coverage.md`.
|
||||
|
||||
| Code | Risk | Diagnostic Question |
|
||||
|------|------|---------------------|
|
||||
@@ -137,7 +143,7 @@ and fixed structural headers from the template below (`Findings`, `Summary`,
|
||||
````
|
||||
# Brooks-Lint Review
|
||||
|
||||
**Mode:** [PR Review / Architecture Audit / Tech Debt Assessment / Test Quality Review]
|
||||
**Mode:** [PR Review / Architecture Audit / Tech Debt Assessment / Test Quality Review / Health Dashboard / Full Sweep]
|
||||
**Scope:** [file(s), directory, or description of what was reviewed]
|
||||
**Health Score:** XX/100
|
||||
|
||||
@@ -196,7 +202,10 @@ Remedy: ...
|
||||
## Remedy Mode
|
||||
|
||||
When the user passes `--fix` or asks to "fix the findings", read
|
||||
`remedy-guide.md` from the `_shared/` directory before writing the report.
|
||||
`remedy-guide.md` from the `_shared/` directory before writing the report. It
|
||||
sharpens each Remedy into a concrete action — the diagnostic modes still do not
|
||||
edit files. Full Sweep is the mode that applies fixes, and it follows
|
||||
`brooks-sweep/sweep-guide.md` instead.
|
||||
|
||||
## Health Score Calculation
|
||||
|
||||
@@ -209,9 +218,7 @@ Base score: 100. Per-finding deductions depend on the `strictness` preset
|
||||
| `balanced` (default) | −15 | −5 | −1 |
|
||||
| `legacy-friendly` | −8 | −3 | −1 |
|
||||
|
||||
Floor: 0 (score cannot go below 0). The preset changes only the score weighting and
|
||||
framing — every finding is still reported in full. Under `legacy-friendly`, lead the
|
||||
**Summary** with the three highest-leverage fixes so a first run is not a wall of Criticals.
|
||||
Floor: 0 (score cannot go below 0).
|
||||
|
||||
## History Tracking
|
||||
|
||||
@@ -240,7 +247,9 @@ After reporting Warning or Suggestion findings, offer:
|
||||
|
||||
For each finding one at a time (lowest severity first): show title, ask `[a]ccept / [d]ismiss / [f]defer / [s]kip`; wait for reply before moving to the next.
|
||||
|
||||
**Dismiss:** ask one-line reason → append to `.brooks-lint.yaml` under `suppress:` → downgraded to info in future runs.
|
||||
**Dismiss:** ask one-line reason → append to `.brooks-lint.yaml` under `suppress:` →
|
||||
downgraded to info in future runs. Entry fields: `risk` (code), `pattern` (file glob),
|
||||
`reason` (required), `date` (when it was dismissed).
|
||||
|
||||
**Defer:** same as dismiss, add `expires: YYYY-MM-DD` (default 90 days) → resurfaces at original severity after expiry.
|
||||
|
||||
|
||||
+3
-4
@@ -42,7 +42,6 @@ process:
|
||||
|
||||
## Config Validation additions
|
||||
|
||||
The following codes are valid in `disable`, `focus`, and `severity`:
|
||||
- Standard: `R1`–`R6`, `T1`–`T6`
|
||||
- Custom: any `Cx` code defined in `custom_risks`
|
||||
- Any other code: skip it and emit `"Config warning: X is not a valid risk code"`
|
||||
Extends the Config Validation rules in `common.md`: alongside `R1`–`R6` and `T1`–`T6`,
|
||||
any `Cx` code defined in `custom_risks` is a valid target for `disable`, `focus`, and
|
||||
`severity`. Anything else is still skipped with a config warning.
|
||||
|
||||
+37
-60
@@ -30,18 +30,12 @@ Cognitive load beyond working memory causes mistakes, avoidance, and blocks the
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Long Method | Fowler — Refactoring | Long Method |
|
||||
| Long Parameter List | Fowler — Refactoring | Long Parameter List |
|
||||
| Message Chains | Fowler — Refactoring | Message Chains |
|
||||
| Flag Arguments | Fowler — Refactoring | Flag Arguments |
|
||||
| Primitive Obsession | Fowler — Refactoring | Primitive Obsession |
|
||||
| Function length and nesting | McConnell — Code Complete | Ch. 7: High-Quality Routines |
|
||||
| Variable naming | McConnell — Code Complete | Ch. 11: The Power of Variable Names |
|
||||
| Magic numbers | McConnell — Code Complete | Ch. 12: Fundamental Data Types |
|
||||
| Domain name mismatch | Evans — Domain-Driven Design | Ubiquitous Language |
|
||||
| Shallow Module | Ousterhout — A Philosophy of Software Design | Ch. 4: Modules Should Be Deep |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Fowler — Refactoring | Long Method · Long Parameter List · Message Chains · Flag Arguments · Primitive Obsession |
|
||||
| McConnell — Code Complete | Ch. 7: High-Quality Routines (length, nesting) · Ch. 11: The Power of Variable Names · Ch. 12: Fundamental Data Types (magic numbers) |
|
||||
| Evans — Domain-Driven Design | Ubiquitous Language (domain name mismatch) |
|
||||
| Ousterhout — A Philosophy of Software Design | Ch. 4: Modules Should Be Deep (Shallow Module) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -84,17 +78,14 @@ Each change ripples to unrelated modules, slowing velocity and multiplying regre
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Shotgun Surgery | Fowler — Refactoring | Shotgun Surgery |
|
||||
| Divergent Change | Fowler — Refactoring | Divergent Change |
|
||||
| Feature Envy | Fowler — Refactoring | Feature Envy |
|
||||
| Inappropriate Intimacy | Fowler — Refactoring | Inappropriate Intimacy |
|
||||
| Orthogonality violation | Hunt & Thomas — The Pragmatic Programmer | Ch. 2: Orthogonality |
|
||||
| DIP violation | Martin — Clean Architecture | Dependency Inversion Principle |
|
||||
| High change propagation radius | Brooks — The Mythical Man-Month | Ch. 2: Brooks's Law (communication overhead) |
|
||||
| Hyrum's Law | Winters et al. — Software Engineering at Google | Ch. 1: Hyrum's Law |
|
||||
| Information Leakage | Ousterhout — A Philosophy of Software Design | Ch. 5: Information Hiding and Leakage |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Fowler — Refactoring | Shotgun Surgery · Divergent Change · Feature Envy · Inappropriate Intimacy |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | Ch. 2: Orthogonality |
|
||||
| Martin — Clean Architecture | Dependency Inversion Principle |
|
||||
| Brooks — The Mythical Man-Month | Ch. 2: Brooks's Law (communication overhead, propagation radius) |
|
||||
| Winters et al. — Software Engineering at Google | Ch. 1: Hyrum's Law |
|
||||
| Ousterhout — A Philosophy of Software Design | Ch. 5: Information Hiding and Leakage |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -128,13 +119,11 @@ Multiple copies drift apart silently. DRY is about decisions, not code lines.
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Code duplication | Fowler — Refactoring | Duplicate Code |
|
||||
| Parallel Inheritance | Fowler — Refactoring | Parallel Inheritance Hierarchies |
|
||||
| DRY violation | Hunt & Thomas — The Pragmatic Programmer | DRY: Don't Repeat Yourself |
|
||||
| Inconsistent naming | Evans — Domain-Driven Design | Ubiquitous Language |
|
||||
| Alternative Classes | Fowler — Refactoring | Alternative Classes with Different Interfaces |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Fowler — Refactoring | Duplicate Code · Parallel Inheritance Hierarchies · Alternative Classes with Different Interfaces |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | DRY: Don't Repeat Yourself |
|
||||
| Evans — Domain-Driven Design | Ubiquitous Language (inconsistent naming) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -172,16 +161,13 @@ Accidental complexity accumulates addition by addition until developers fight sc
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Speculative Generality | Fowler — Refactoring | Speculative Generality |
|
||||
| Lazy Class | Fowler — Refactoring | Lazy Class |
|
||||
| Middle Man | Fowler — Refactoring | Middle Man |
|
||||
| Switch Statements | Fowler — Refactoring | Switch Statements |
|
||||
| Second System Effect | Brooks — The Mythical Man-Month | Ch. 5: The Second-System Effect |
|
||||
| YAGNI violations | McConnell — Code Complete | Ch. 5: Design in Construction |
|
||||
| Over-engineering | Hunt & Thomas — The Pragmatic Programmer | Topic 4: Good-Enough Software |
|
||||
| Tactical programming debt | Ousterhout — A Philosophy of Software Design | Ch. 3: Strategic vs. Tactical Programming |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Fowler — Refactoring | Speculative Generality · Lazy Class · Middle Man · Switch Statements |
|
||||
| Brooks — The Mythical Man-Month | Ch. 5: The Second-System Effect |
|
||||
| McConnell — Code Complete | Ch. 5: Design in Construction (YAGNI) |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | Topic 4: Good-Enough Software (over-engineering) |
|
||||
| Ousterhout — A Philosophy of Software Design | Ch. 3: Strategic vs. Tactical Programming |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -222,17 +208,12 @@ When business logic depends on infrastructure, infrastructure changes cascade in
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Dependency cycles | Martin — Clean Architecture | Acyclic Dependencies Principle (ADP) |
|
||||
| DIP violation | Martin — Clean Architecture | Dependency Inversion Principle (DIP) |
|
||||
| Instability direction | Martin — Clean Architecture | Stable Dependencies Principle (SDP) |
|
||||
| Abstraction mismatch | Martin — Clean Architecture | Stable Abstractions Principle (SAP) |
|
||||
| ISP violation | Martin — Clean Architecture | Interface Segregation Principle (ISP) |
|
||||
| Conceptual integrity | Brooks — The Mythical Man-Month | Ch. 4: Conceptual Integrity |
|
||||
| Law of Demeter | Hunt & Thomas — The Pragmatic Programmer | Ch. 5: Decoupling and the Law of Demeter |
|
||||
| SOLID violations | Martin — Clean Architecture | Single Responsibility, Open/Closed Principles |
|
||||
| Diamond dependency / upgrade blockage | Winters et al. — Software Engineering at Google | Ch. 21: Dependency Management |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Martin — Clean Architecture | Acyclic Dependencies (ADP, cycles) · Dependency Inversion (DIP) · Stable Dependencies (SDP, instability direction) · Stable Abstractions (SAP) · Interface Segregation (ISP) · Single Responsibility · Open/Closed |
|
||||
| Brooks — The Mythical Man-Month | Ch. 4: Conceptual Integrity |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | Ch. 5: Decoupling and the Law of Demeter |
|
||||
| Winters et al. — Software Engineering at Google | Ch. 21: Dependency Management (diamond dependency, upgrade blockage) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -271,15 +252,11 @@ Code that mismatches business language forces mental translation. Over time it m
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Anemic Domain Model | Evans — Domain-Driven Design | Domain Model pattern |
|
||||
| Ubiquitous Language drift | Evans — Domain-Driven Design | Ubiquitous Language |
|
||||
| Bounded context violation | Evans — Domain-Driven Design | Bounded Context |
|
||||
| Data Class | Fowler — Refactoring | Data Class |
|
||||
| Refused Bequest | Fowler — Refactoring | Refused Bequest |
|
||||
| Feature Envy | Fowler — Refactoring | Feature Envy |
|
||||
| LSP violation | Martin — Clean Architecture | Liskov Substitution Principle (LSP) |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Evans — Domain-Driven Design | Domain Model pattern (Anemic Domain Model) · Ubiquitous Language · Bounded Context |
|
||||
| Fowler — Refactoring | Data Class · Refused Bequest · Feature Envy |
|
||||
| Martin — Clean Architecture | Liskov Substitution Principle (LSP) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
|
||||
+7
-1
@@ -1,5 +1,11 @@
|
||||
# Remedy Guide — Actionable Fix Mode
|
||||
|
||||
**Applies to the diagnostic modes only** (PR Review, Architecture Audit, Tech Debt,
|
||||
Test Quality, Health Dashboard). They never write to the codebase — `--fix` there
|
||||
means "make the Remedy specific enough to act on", not "apply it". Full Sweep
|
||||
(`/brooks-sweep`) is the one mode that edits files; it follows
|
||||
`brooks-sweep/sweep-guide.md`, which owns its own fix-classification and revert rules.
|
||||
|
||||
When `--fix` is active, enhance every finding's Remedy field to be directly actionable:
|
||||
|
||||
## Remedy Enhancement Rules
|
||||
@@ -32,6 +38,6 @@ After the standard report, add a **Fix Summary** section:
|
||||
| R5 — Circular dep | manual | src/models/ ↔ src/services/ | Introduce interface boundary |
|
||||
|
||||
## What NOT to do
|
||||
- Do NOT modify any files. Phase 1 is diagnosis + actionable plan only.
|
||||
- Do NOT modify any files. Diagnosis + actionable plan is the whole deliverable.
|
||||
- Do NOT generate diffs or code blocks. The Remedy text IS the deliverable.
|
||||
- Do NOT re-score. The Health Score reflects current state, not projected state.
|
||||
|
||||
+28
-35
@@ -24,12 +24,10 @@ Unclear test intent breeds distrust, missed failures, and duplicates — one ste
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Assertion Roulette | Meszaros — xUnit Test Patterns | Assertion Roulette (p.224) |
|
||||
| Mystery Guest | Meszaros — xUnit Test Patterns | Mystery Guest (p.411) |
|
||||
| General Fixture | Meszaros — xUnit Test Patterns | General Fixture (p.316) |
|
||||
| Test naming | Osherove — The Art of Unit Testing | method_scenario_expected naming convention |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Meszaros — xUnit Test Patterns | Assertion Roulette (p.224) · Mystery Guest (p.411) · General Fixture (p.316) |
|
||||
| Osherove — The Art of Unit Testing | method_scenario_expected naming convention |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -66,12 +64,11 @@ Brittle tests punish refactoring — eventually developers stop refactoring and
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Eager Test | Meszaros — xUnit Test Patterns | Eager Test (p.228) |
|
||||
| Erratic Test | Meszaros — xUnit Test Patterns | Erratic Test |
|
||||
| Implementation coupling | Osherove — The Art of Unit Testing | Test isolation principle |
|
||||
| Orthogonality violation | Hunt & Thomas — The Pragmatic Programmer | Ch. 2: Orthogonality |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Meszaros — xUnit Test Patterns | Eager Test (p.228) · Erratic Test |
|
||||
| Osherove — The Art of Unit Testing | Test isolation principle (implementation coupling) |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | Ch. 2: Orthogonality |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -105,11 +102,10 @@ Duplicated tests must change in multiple places and create false confidence with
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Test Code Duplication | Meszaros — xUnit Test Patterns | Test Code Duplication (p.213) |
|
||||
| Lazy Test | Meszaros — xUnit Test Patterns | Lazy Test (p.232) |
|
||||
| DRY violation in tests | Hunt & Thomas — The Pragmatic Programmer | DRY: Don't Repeat Yourself |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Meszaros — xUnit Test Patterns | Test Code Duplication (p.213) · Lazy Test (p.232) |
|
||||
| Hunt & Thomas — The Pragmatic Programmer | DRY: Don't Repeat Yourself |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -144,13 +140,11 @@ Mock abuse produces tests that pass while verifying nothing — production code
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Mock count > 3 | Osherove — The Art of Unit Testing | Mock usage guidelines |
|
||||
| Testing mock behavior | Meszaros — xUnit Test Patterns | Behavior Verification (p.544) |
|
||||
| Test-only production methods | Feathers — Working Effectively with Legacy Code | Ch. 3: Sensing and Separation |
|
||||
| Hard-Coded Test Data | Meszaros — xUnit Test Patterns | Hard-Coded Test Data (p.534) |
|
||||
| Incomplete Mock | Osherove — The Art of Unit Testing | Mock completeness requirement |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Meszaros — xUnit Test Patterns | Behavior Verification (p.544) · Hard-Coded Test Data (p.534) |
|
||||
| Osherove — The Art of Unit Testing | Mock usage guidelines (count > 3) · Mock completeness requirement (Incomplete Mock) |
|
||||
| Feathers — Working Effectively with Legacy Code | Ch. 3: Sensing and Separation (test-only production methods) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -185,11 +179,11 @@ Coverage measures execution, not verification. 90% line coverage can still miss
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Legacy code = no tests | Feathers — Working Effectively with Legacy Code | Ch. 1: "Legacy code is code without tests" |
|
||||
| Change coverage vs line coverage | Google — How Google Tests Software | Ch. 11: Testing at Google Scale |
|
||||
| Happy-path only | Osherove — The Art of Unit Testing | Test completeness principle |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Feathers — Working Effectively with Legacy Code | Ch. 1: "Legacy code is code without tests" |
|
||||
| Google — How Google Tests Software | Ch. 11: Testing at Google Scale (change vs line coverage) |
|
||||
| Osherove — The Art of Unit Testing | Test completeness principle (happy-path only) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
@@ -226,12 +220,11 @@ Wrong suite shape is slow and expensive — not from bad tests, but from using t
|
||||
|
||||
### Sources
|
||||
|
||||
| Symptom | Book | Principle / Smell |
|
||||
|---------|------|-------------------|
|
||||
| Inverted pyramid | Google — How Google Tests Software | 70:20:10 unit:integration:E2E ratio |
|
||||
| No seam points | Feathers — Working Effectively with Legacy Code | Ch. 4: Seam Model |
|
||||
| Missing Characterization Tests | Feathers — Working Effectively with Legacy Code | Ch. 13: Characterization Tests |
|
||||
| Suite execution time | Meszaros — xUnit Test Patterns | Slow Tests (p. 253) |
|
||||
| Book | Principle / Smell |
|
||||
|------|-------------------|
|
||||
| Google — How Google Tests Software | 70:20:10 unit:integration:E2E ratio (inverted pyramid) |
|
||||
| Feathers — Working Effectively with Legacy Code | Ch. 4: Seam Model · Ch. 13: Characterization Tests |
|
||||
| Meszaros — xUnit Test Patterns | Slow Tests (p. 253, suite execution time) |
|
||||
|
||||
### Severity Guide
|
||||
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
# Phase boundaries
|
||||
|
||||
A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. The definition is fuzzy on purpose: a phase ends when you think *"ok, we're done with that"*.
|
||||
|
||||
The **phase boundary** is the gap between two phases, and it is the only place this decision belongs. Mid-phase there is no decision to make — continue, or split the work that's left into subagents. Compacting mid-phase makes the agent lose the thread.
|
||||
|
||||
## The five options
|
||||
|
||||
| Option | What it does |
|
||||
| ------------ | --------------------------------------------------------------- |
|
||||
| **Continue** | Stay in the session. No context switch at all. |
|
||||
| **`/clear`** | Empty the context window and start from nothing. |
|
||||
| **`/handoff`** | Write a portable markdown file and seed a session anywhere with it. |
|
||||
| **Subagent** | Send the task to its own context window and get a report back. |
|
||||
| **`/compact`** | Compress this context and seed a fresh session with the summary. |
|
||||
|
||||
## The tree
|
||||
|
||||
Work top to bottom at the boundary. The first **yes** wins.
|
||||
|
||||
**1. Can you continue in this session?** Two things make the answer yes: the next phase needs this phase as a **primary source**, or you have enough [smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone) left (~150k tokens) for the next phase to fit. Grilling → implementation is the standard yes: the implementation wants the reasoning verbatim, not a summary of it. Continue costs nothing and loses nothing, so rule it out before anything else.
|
||||
|
||||
**2. Is the context irrelevant to what comes next?** Is everything in this session — the exploration, the decisions, the dead ends — disposable? If so, **`/clear`**. It is the cheapest move on the board: it takes no time and hands back the whole window. `/clear` also isn't terminal — the old session stays resumable.
|
||||
|
||||
The cost of getting this wrong is one-way. Clear a *relevant* context and you lose the **why** behind what you built, and no amount of reading the diff back gets it returned.
|
||||
|
||||
**3. Do you need to hand off?** `/handoff` is narrow. You need it only when you are:
|
||||
|
||||
- swapping to a **new harness** (Claude → Codex),
|
||||
- moving to a **new directory** or repo,
|
||||
- sending the work to a **colleague**,
|
||||
- or forking a side task you found **mid-phase** without derailing what you're doing.
|
||||
|
||||
That list is the whole clause. What `/handoff` buys is **portability** — a file that travels. If nothing is travelling, you don't need it.
|
||||
|
||||
**4. Can the task be done AFK?** Is it scoped tightly enough to run with you away from the keyboard, no steering? Then send it to a **subagent** and leave this session untouched. Automated review is the standard case: the agent reads the diff and reports, and you aren't needed while it does.
|
||||
|
||||
**5. Otherwise, `/compact`.** Relevant context, same harness, same directory, and you need to stay in the loop — this is where the tree lands, and it lands here often. Pass it an instruction (`/compact we're going to QA this area`) so the summary keeps what the next phase needs.
|
||||
|
||||
`/compact` is the **default, not the first reach**. It sits at the bottom because the four questions above it are all cheaper or more precise. The failure mode when people start here is a fresh session that is confidently wrong about a decision the summary flattened.
|
||||
|
||||
## Primary and secondary sources
|
||||
|
||||
Every move except **Continue** turns a **primary source** into a **secondary source** — the session as it happened, replaced by a summary of it. The trade is always the same shape:
|
||||
|
||||
| Source | Information | Noise | Room to move |
|
||||
| --------------------------------- | ----------- | ----- | ------------ |
|
||||
| Primary (Continue) | Full | Lots | Little |
|
||||
| Secondary (`/compact`, `/handoff`) | Lossy | Less | Lots |
|
||||
|
||||
This is why question 1 comes first. You only pay the lossiness when staying costs more than it saves.
|
||||
|
||||
## These are judgement calls
|
||||
|
||||
The questions are not objective — each has taste in it, and the same boundary can go two ways on two days. The value is in asking them **in order**, at the boundary rather than in the middle of the work.
|
||||
Vendored
-90
@@ -1,90 +0,0 @@
|
||||
---
|
||||
name: ask-matt
|
||||
description: Ask which skill or flow fits your situation. A router over the skills in this repo.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Ask Matt
|
||||
|
||||
You don't remember every skill, so ask.
|
||||
|
||||
A **flow** is a path through the skills. Most paths run along one **main flow**, and two **on-ramps** merge onto it. Everything else is standalone, or a vocabulary layer that runs underneath.
|
||||
|
||||
## The main flow: idea → ship
|
||||
|
||||
The route most work travels. You have an idea and want it built.
|
||||
|
||||
1. **`/grill-with-docs`** — sharpen the idea by interview. Start here whenever you are **working in a working directory**: it's stateful, retaining what it learns in `CONTEXT.md` and ADRs. (No working directory? Use `/grill-me` — see Standalone. Both run the same `/grilling` primitive; `grill-with-docs` is the one that leaves a paper trail, which makes it the better of the two whenever a repo is there to leave it in.)
|
||||
2. **Branch — can you settle every question in conversation?** If a question needs a runnable answer (state, business logic, a UI you have to see), detour through a prototype, bridged by **`/handoff`** in both directions (a prototype lives in its own directory, which is exactly what `/handoff` is for — see Phase boundaries):
|
||||
- **`/handoff`** out, then open a fresh session against that file,
|
||||
- **`/prototype`** to answer the question with throwaway code,
|
||||
- **`/handoff`** back what you learned, and reference it from the original idea thread.
|
||||
3. **Branch — is this a multi-session build?**
|
||||
- **Yes** → **`/to-spec`** (turn the thread into a spec), then **`/to-tickets`** to split it into tracer-bullet tickets, each declaring its **blocking edges**. On a local tracker that's one file per ticket under `.scratch/<feature>/issues/`, worked blockers-first by hand; on a real tracker the edges become native blocking links, so any ticket whose blockers are done can be grabbed — kick off **`/implement`** per ticket, **`/clear`ing context between each one**. Each ticket is self-contained, so the last one's context is disposable.
|
||||
- **No** → **`/implement`** right here, in the same context window.
|
||||
|
||||
Either way, **`/implement`** builds each issue by driving **`/tdd`** internally — one red-green slice at a time — then closes out by running **`/code-review`**, a two-axis review (Standards + Spec) of the diff, before committing. Reach for **`/tdd`** on its own when you just want to build a concrete behaviour test-first without a full spec, and **`/code-review`** on its own whenever you want to review a branch or PR against a fixed point.
|
||||
|
||||
### Context hygiene
|
||||
|
||||
Keep steps 1–3 in **one unbroken context window** — don't compact or clear until after `/to-tickets` — so the grilling, spec, and tickets all build on the same thinking. Each `/implement` then starts fresh, working from the ticket.
|
||||
|
||||
The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone)**: the window (~150k tokens on state-of-the-art models) within which the model still reasons sharply. If a session approaches it before `/to-tickets`, don't push on degraded — `/compact` at the nearest phase boundary and carry on (see Phase boundaries).
|
||||
|
||||
## On-ramps
|
||||
|
||||
A starting situation that generates work, then merges onto the main flow.
|
||||
|
||||
- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up.
|
||||
|
||||
Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Tickets that `/to-tickets` produced are already agent-ready, so **don't triage them**.
|
||||
|
||||
- **Something's broken** → **`/diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on *this* bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down.
|
||||
|
||||
- **A huge, foggy effort — a greenfield project or a huge feature build, too big for one session** → **`/wayfinder`**, the most cognitively demanding flow here. When the way from here to the destination isn't visible yet, it charts a **shared map** of **decision tickets** on the issue tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog is pushed back and the way is clear. Where **`/grill-with-docs`** sharpens an idea you can hold in one session, wayfinder is for the idea you can't — and it's slower and denser, so save it for exactly that, never a well-scoped feature.
|
||||
|
||||
When the map clears, **it hands off, it doesn't build**: merge onto the main flow at **`/to-spec`**, which collapses the map's linked decisions into a buildable plan, then `/to-tickets` and `/implement` as usual. Looping the map straight into `/implement` skips that collapse and throws the linked detail away — go straight to `/implement` only when the effort turned out genuinely small.
|
||||
|
||||
## Codebase health
|
||||
|
||||
Not feature work — upkeep.
|
||||
|
||||
- **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. It's the survey that finds the candidates; **`/codebase-design`** (below) is the bench you design the chosen one on.
|
||||
|
||||
## Vocabulary underneath
|
||||
|
||||
Two model-invoked references that run *beneath* the other skills — each the single source of truth for its vocabulary. Reach for them directly when the **words**, not the process, are the problem; or let the skills above pull them in.
|
||||
|
||||
- **`/domain-modeling`** — sharpen the project's *domain* language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary.
|
||||
- **`/codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's *shape*: a lot of behaviour behind a small interface at a clean seam. `/tdd` and `/improve-codebase-architecture` both speak it.
|
||||
|
||||
## Phase boundaries
|
||||
|
||||
A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. At the **boundary** between two of them you have five options, and picking between them is the fuzziest decision in this whole map:
|
||||
|
||||
- **Continue** — stay put. Costs nothing, loses nothing.
|
||||
- **`/clear`** — empty the window, when nothing here matters to what's next.
|
||||
- **`/handoff`** — write a portable markdown file. Narrow: only for a **new harness**, a **new directory**, a **colleague**, or forking a side task **mid-phase**. What it buys is portability.
|
||||
- **Subagent** — send a tightly-scoped task to its own window and get a report back.
|
||||
- **`/compact`** — compress this context and seed a fresh session with it. The **default**, at the bottom of the tree rather than the first reach.
|
||||
|
||||
Read [PHASE-BOUNDARIES.md](PHASE-BOUNDARIES.md) for the ordered tree — the five questions, the reasoning behind each branch, and why the primary-source cost makes **Continue** the one to rule out first. Make the decision **at** a boundary; mid-phase, continue or split the rest into subagents.
|
||||
|
||||
## Standalone
|
||||
|
||||
Off the main flow entirely.
|
||||
|
||||
- **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but **stateless**: it saves nothing locally and builds no `CONTEXT.md`. Reach for it when you are **not working in a working directory** — sharpening a plan, a design, a piece of writing, anything with no repo under it. If you are in a working directory, use `/grill-with-docs` instead: it runs the same interview and leaves a paper trail, so it is strictly the better one.
|
||||
- **`/grilling`** — the interview primitive itself: rounds, the frontier, facts are the agent's job and decisions are yours. `/grill-me` and `/grill-with-docs` are the two named ways in, and `/triage`, `/wayfinder` and `/improve-codebase-architecture` all run it internally. Reach for it directly only when you want the interview with no wrapper around it.
|
||||
- **`/resolving-merge-conflicts`** — work an in-progress merge or rebase conflict hunk by hunk, resolving by **intent** traced to each side's primary source rather than by picking lines, then finish the operation. It never runs `--abort`. Standalone and off every flow: reach for it when you are already mid-conflict.
|
||||
- **`/prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway is a constraint on how the code is written, not a promise to destroy it: the answer folds into the real code, and the prototype itself is kept as a **primary source** on a `prototype/<name>` branch out of main, pointed at from the implementation issue. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper.
|
||||
- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it.
|
||||
- **`/to-questionnaire`** — when the thing blocking you isn't in your head or the codebase but in **someone else's**, this writes them a questionnaire to fill in. It's the inverse of `/grill-me`: instead of interviewing you about the subject, it interviews you about the **send** — who it's going to, what you need back — and aims the questions at the gap. What comes back is material for `/grill-with-docs` or `/to-spec`.
|
||||
- **`/wizard`** — for the steps only a **human** can take: provisioning infrastructure, setting up credentials or CI secrets, clicking through an unfamiliar third-party dashboard, running a one-off migration or cutover. It generates an interactive bash script that opens each URL, captures each value, and writes it into `.env` and GitHub secrets — so the procedure stops being something you re-explain to an agent every time. Model-invoked, so the agent reaches for it the moment it hits a wall only you can pass. If the agent could just do it itself, it should; this is for where a human is genuinely in the loop.
|
||||
- **`/wait-what`** — the corrective for a message that didn't land. Use it mid-conversation, inside any other skill, and the agent re-pitches what it just said with the context you were missing, in plain English, using the `CONTEXT.md` vocabulary. It works after the fact; `/grill-with-docs` is the upfront cure, because a shared language agreed early is what stops the jargon arriving at all.
|
||||
- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace.
|
||||
- **`/writing-for-agents`** — reference for writing documents agents consume: skills, AGENTS.md, pointed-at docs.
|
||||
|
||||
## Precondition
|
||||
|
||||
**`/setup-matt-pocock-skills`** — run before your first engineering flow to configure the issue tracker, triage labels, and doc layout the other skills assume. Custom issue trackers also work.
|
||||
@@ -1,5 +0,0 @@
|
||||
interface:
|
||||
display_name: "Ask Matt"
|
||||
short_description: "Find the right skill or workflow"
|
||||
policy:
|
||||
allow_implicit_invocation: false
|
||||
+8
-6
@@ -16,10 +16,12 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/decay-risks.md` for symptom definitions and source attributions
|
||||
4. Read `architecture-guide.md` in this directory for the audit framework
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/decay-risks.md` — symptom definitions and source attributions
|
||||
4. `architecture-guide.md` (this directory) — the audit framework
|
||||
|
||||
## Process
|
||||
|
||||
@@ -28,8 +30,8 @@ description: >
|
||||
directory and follow it instead of `architecture-guide.md`. This mode explains rather
|
||||
than diagnoses — no Health Score, no Iron Law findings.
|
||||
|
||||
**If the user has not specified files or a directory to audit:** apply Auto Scope
|
||||
Detection from `../_shared/common.md` to determine the audit scope before proceeding.
|
||||
**Scope:** if the user did not specify files or a directory, apply Auto Scope Detection
|
||||
(`../_shared/common.md`) first.
|
||||
|
||||
1. Gather codebase context and draw the module dependency graph as Mermaid (Steps 0–1 of the guide)
|
||||
2. Scan for each decay risk in the order specified (Steps 2–4 of the guide)
|
||||
|
||||
+3
-11
@@ -54,7 +54,6 @@ Before evaluating any risk, map the dependencies as a Mermaid diagram. Use this
|
||||
graph TD
|
||||
subgraph UI
|
||||
WebApp
|
||||
MobileApp
|
||||
end
|
||||
|
||||
subgraph Domain
|
||||
@@ -65,16 +64,12 @@ graph TD
|
||||
|
||||
subgraph Infrastructure
|
||||
Database
|
||||
MessageQueue
|
||||
end
|
||||
|
||||
WebApp --> AuthService
|
||||
WebApp --> OrderService
|
||||
MobileApp --> AuthService
|
||||
MobileApp --> OrderService
|
||||
OrderService --> PaymentService
|
||||
OrderService --> Database
|
||||
OrderService --> MessageQueue
|
||||
PaymentService --> Database
|
||||
AuthService -.->|circular| OrderService
|
||||
|
||||
@@ -84,14 +79,11 @@ graph TD
|
||||
|
||||
class PaymentService critical
|
||||
class OrderService warning
|
||||
class Database,MessageQueue,AuthService,WebApp,MobileApp clean
|
||||
class Database,AuthService,WebApp clean
|
||||
````
|
||||
|
||||
Draw the graph structure first — nodes, subgraphs, and edges — without any `classDef` or
|
||||
`class` lines. You cannot assign colors until you have completed the risk scan in Steps 2–4.
|
||||
|
||||
**After completing Step 4**, return to this graph and add the `classDef` and `class` lines
|
||||
based on findings. The example above shows the final colored output.
|
||||
The example shows the final colored output. Draw nodes, subgraphs, and edges first; the
|
||||
`classDef` and `class` lines can only be written after the risk scan (Rule 6 below).
|
||||
|
||||
Rules:
|
||||
1. **Nodes** — Use top-level directories or services as nodes, not individual files
|
||||
|
||||
+8
-6
@@ -16,15 +16,17 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/decay-risks.md` for symptom definitions and source attributions
|
||||
4. Read `debt-guide.md` in this directory for the debt classification framework
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/decay-risks.md` — symptom definitions and source attributions
|
||||
4. `debt-guide.md` (this directory) — the debt classification framework
|
||||
|
||||
## Process
|
||||
|
||||
**If the user has not described the codebase or pointed to specific areas:** apply Auto
|
||||
Scope Detection from `../_shared/common.md` to determine the assessment scope before proceeding.
|
||||
**Scope:** if the user did not describe the codebase or point to specific areas, apply
|
||||
Auto Scope Detection (`../_shared/common.md`) first.
|
||||
|
||||
1. Scan for all six decay risks (Step 1 of the guide); list every finding before scoring
|
||||
2. Apply the Pain × Spread priority formula and classify debt intent (Steps 2–3 of the guide)
|
||||
|
||||
+9
-7
@@ -18,16 +18,18 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/decay-risks.md` for production risk symptom definitions
|
||||
4. Read `../_shared/test-decay-risks.md` for test risk symptom definitions
|
||||
5. Read `health-guide.md` in this directory for the dashboard orchestration process
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/decay-risks.md` — production risk symptoms
|
||||
4. `../_shared/test-decay-risks.md` — test risk symptoms
|
||||
5. `health-guide.md` (this directory) — the dashboard orchestration process
|
||||
|
||||
## Process
|
||||
|
||||
**If the user has not specified a project or directory:** apply Auto Scope Detection
|
||||
from `../_shared/common.md` to determine the review scope before proceeding.
|
||||
**Scope:** if the user did not specify a project or directory, apply Auto Scope Detection
|
||||
(`../_shared/common.md`) first.
|
||||
|
||||
1. Run abbreviated scans across all four dimensions (Step 1 of the guide)
|
||||
2. Compute per-dimension and composite Health Scores with weighting (Step 2 of the guide)
|
||||
|
||||
+8
-6
@@ -18,15 +18,17 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/decay-risks.md` for symptom definitions and source attributions
|
||||
4. Read `pr-review-guide.md` in this directory for the analysis process
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/decay-risks.md` — symptom definitions and source attributions
|
||||
4. `pr-review-guide.md` (this directory) — the analysis process
|
||||
|
||||
## Process
|
||||
|
||||
**If the user has not specified files or pasted code:** apply Auto Scope Detection
|
||||
from `../_shared/common.md` to determine the review scope before proceeding.
|
||||
**Scope:** if the user did not specify files or paste code, apply Auto Scope Detection
|
||||
(`../_shared/common.md`) first.
|
||||
|
||||
1. Understand the review scope, then scan for each decay risk in the order specified (Steps 1–6 of the guide)
|
||||
2. Run the Quick Test Check (Step 7 of the guide) — skip for docs-only or non-production changes
|
||||
|
||||
+15
-17
@@ -86,23 +86,7 @@ If no new imports and no structural changes → skip, no finding.
|
||||
- Does any new class hold only data with no behavior (pure data bag), where behavior was expected?
|
||||
- Does any new method put logic that belongs to the domain in a service or utility layer?
|
||||
|
||||
---
|
||||
|
||||
## Severity Calibration
|
||||
|
||||
Apply the Iron Law format from `../_shared/common.md`. Each risk in `../_shared/decay-risks.md` has its own Severity
|
||||
Guide with numeric thresholds — use those as the primary reference. When a finding sits
|
||||
on the boundary between two tiers, use this as a tiebreaker:
|
||||
- 🔴 Critical — actively breaking velocity or creating production risk *today*
|
||||
- 🟡 Warning — will if left unaddressed through the next few features
|
||||
- 🟢 Suggestion — worth fixing when nearby, not urgent
|
||||
|
||||
When multiple findings exist, list Critical items first. If there are more than 5 findings,
|
||||
add a one-line "Recommended fix order" at the end of the Findings section.
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Quick Test Check
|
||||
### Step 7: Quick Test Check
|
||||
|
||||
*Run this last. Three signals only — this is not a full Mode 4 review.*
|
||||
|
||||
@@ -156,6 +140,20 @@ Label the risk as the test decay risk name (e.g., "Coverage Illusion", "Mock Abu
|
||||
|
||||
---
|
||||
|
||||
## Severity Calibration
|
||||
|
||||
Apply the Iron Law format from `../_shared/common.md`. Each risk in `../_shared/decay-risks.md` has its own Severity
|
||||
Guide with numeric thresholds — use those as the primary reference. When a finding sits
|
||||
on the boundary between two tiers, use this as a tiebreaker:
|
||||
- 🔴 Critical — actively breaking velocity or creating production risk *today*
|
||||
- 🟡 Warning — will if left unaddressed through the next few features
|
||||
- 🟢 Suggestion — worth fixing when nearby, not urgent
|
||||
|
||||
When multiple findings exist, list Critical items first. If there are more than 5 findings,
|
||||
add a one-line "Recommended fix order" at the end of the Findings section.
|
||||
|
||||
---
|
||||
|
||||
## Output
|
||||
|
||||
Use the standard Report Template from `../_shared/common.md`.
|
||||
|
||||
+13
-11
@@ -18,21 +18,23 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/decay-risks.md` for production risk symptom definitions
|
||||
4. Read `../_shared/test-decay-risks.md` for test risk symptom definitions
|
||||
5. Read `sweep-guide.md` in this directory for the unified scan and fix process
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/decay-risks.md` — production risk symptoms
|
||||
4. `../_shared/test-decay-risks.md` — test risk symptoms
|
||||
5. `sweep-guide.md` (this directory) — the unified scan and fix process
|
||||
|
||||
## Process
|
||||
|
||||
**If the user has not specified a project or directory:** apply Auto Scope Detection
|
||||
from `../_shared/common.md` to determine the review scope before proceeding.
|
||||
**Scope:** if the user did not specify a project or directory, apply Auto Scope Detection
|
||||
(`../_shared/common.md`) first.
|
||||
|
||||
1. Show pre-flight consent notice and wait for the user's one-time approval (Step 0 of the guide)
|
||||
2. Enumerate scope and initialize the `unresolvable` / `non_critical_rounds` / `fix_log` state (Step 1 of the guide)
|
||||
3. Run the four dimensions in sequence — review, test, debt, audit — each scanning, classifying, applying Safe + Extended-Safe fixes, and verifying via the project test command (Steps 2–5 of the guide)
|
||||
4. Iterate: re-scan modified files + same-module + static consumers; converge on a clean round, retire 3-retry failures to the `unresolvable` set, cap non-critical rounds at 3 (Step 6 of the guide)
|
||||
1. Show the pre-flight consent notice and wait for one-time approval (Step 0 of the guide)
|
||||
2. Enumerate scope and initialize pipeline state (Step 1 of the guide)
|
||||
3. Run the four dimensions in sequence — review, test, debt, audit — each scanning, classifying, fixing, and verifying (Steps 2–5 of the guide)
|
||||
4. Iterate over modified files and their consumers until a clean round or the cap (Step 6 of the guide)
|
||||
5. Aggregate residual and unresolvable items and output the Full Sweep Report (Steps 7–8 of the guide)
|
||||
|
||||
**Mode line in report:** `Full Sweep`
|
||||
|
||||
+1
-1
@@ -222,7 +222,7 @@ Output the final report. Use the standard Report Template from
|
||||
```
|
||||
# Brooks-Lint — Full Sweep Report
|
||||
Mode: Full Sweep | Scope: <files or directory>
|
||||
Config: .brooks-lint.yaml applied (N risks disabled, M paths ignored) # omit if no config
|
||||
Config: .brooks-lint.yaml applied (strictness: <preset>, N risks disabled, M paths ignored) # omit if no config
|
||||
|
||||
## Dimension Summary
|
||||
| Dimension | Scanned | Safe Applied | Extended Applied | Reverted | Residual |
|
||||
|
||||
+8
-6
@@ -18,15 +18,17 @@ description: >
|
||||
|
||||
## Setup
|
||||
|
||||
1. Read `../_shared/common.md` for the Iron Law, Project Config, Report Template, and Health Score rules
|
||||
2. Read `../_shared/source-coverage.md` for book-level coverage, exceptions, and tradeoffs
|
||||
3. Read `../_shared/test-decay-risks.md` for test-space symptom definitions and source attributions
|
||||
4. Read `test-guide.md` in this directory for the test quality review framework
|
||||
Read in order:
|
||||
|
||||
1. `../_shared/common.md` — Iron Law, Project Config, Report Template, Health Score
|
||||
2. `../_shared/source-coverage.md` — book coverage, exceptions, tradeoffs
|
||||
3. `../_shared/test-decay-risks.md` — test-space symptom definitions and sources
|
||||
4. `test-guide.md` (this directory) — the test quality review framework
|
||||
|
||||
## Process
|
||||
|
||||
**If the user has not shared test files or pointed to a test directory:** apply Auto
|
||||
Scope Detection from `../_shared/common.md` to determine the review scope before proceeding.
|
||||
**Scope:** if the user did not share test files or point to a test directory, apply Auto
|
||||
Scope Detection (`../_shared/common.md`) first.
|
||||
|
||||
1. Build the test suite map (guide's "Before You Start" section)
|
||||
2. Scan for each test decay risk in the order specified (Steps 1–4 of the guide)
|
||||
|
||||
+9
-7
@@ -62,8 +62,7 @@ Look for:
|
||||
to the observable behavior?
|
||||
- Are tests coupled to private methods or internal state directly?
|
||||
|
||||
If brittleness is systemic (most tests in the file break on a rename) → 🔴 Critical.
|
||||
If isolated (1–2 brittle tests) → 🟢 Suggestion.
|
||||
Severity: use the T2 Severity Guide in `../_shared/test-decay-risks.md`.
|
||||
|
||||
### Step 2b: Scan for Mock Abuse
|
||||
|
||||
@@ -97,8 +96,8 @@ Look for:
|
||||
- Is the same business scenario covered at unit, integration, and E2E level with no
|
||||
difference in what each layer is testing?
|
||||
|
||||
If duplication is systemic (10 or more instances) → Critical.
|
||||
If localized (3–5 instances) → Warning.
|
||||
Severity: use the T3 Severity Guide in `../_shared/test-decay-risks.md`, with instance
|
||||
counts as the tiebreaker — 🔴 10+ instances, 🟡 3–9, 🟢 1–2.
|
||||
|
||||
### Step 4: Scan for Coverage Illusion and Architecture Mismatch
|
||||
|
||||
@@ -131,9 +130,12 @@ Look for Architecture Mismatch:
|
||||
|
||||
**Test suite performance:** A slow test suite is a first-class maintainability risk — it
|
||||
breaks the fast-feedback loop and causes developers to skip running tests locally.
|
||||
- If the full suite runtime is known and > 10 minutes → 🟡 Warning
|
||||
- If the full suite runtime is > 30 minutes or unknown → 🔴 Critical (unknown suite time
|
||||
means nobody is running it regularly)
|
||||
- If the full suite runtime is > 10 minutes → 🟡 Warning (per the T6 Severity Guide in
|
||||
`../_shared/test-decay-risks.md`; runtime alone does not reach Critical)
|
||||
- Runtime > 30 minutes, or unknown because nobody runs the suite, is still 🟡 Warning —
|
||||
but say so explicitly in the Symptom. It reaches 🔴 Critical only when combined with a
|
||||
Critical T6 condition: legacy code under modification with no seams and no
|
||||
characterization tests, or a fully inverted pyramid
|
||||
- If tests that could be unit tests are integration tests, that is a Performance Mismatch:
|
||||
each misclassified test adds seconds of avoidable wait time
|
||||
|
||||
|
||||
+661
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
---
|
||||
name: cangjie-skill
|
||||
description: Distill a book, long-video transcript, podcast, course, or interview into a coherent set of executable skills. Use when the user asks to "拆书" / "蒸馏一本书" / "把 XX 书做成 skill" / "把这个视频/播客/课程蒸馏成 skill" / "turn a book or video into skills" — i.e. wants the frameworks, principles, and methodologies in long-form content extracted into atomic, reusable Claude skills that an agent can invoke in real-world situations. NOT for simple summarization, book reviews, or role-playing as the author (that is nuwa-skill's job).
|
||||
---
|
||||
|
||||
# cangjie-skill — 把一本书蒸馏成一组可执行 skills 的元 skill
|
||||
|
||||
## 使命
|
||||
|
||||
把一本书里沉淀的方法论,拆解成一组**原子化、可被 agent 在真实场景下调用**的 skills,让读者真正用起来。
|
||||
|
||||
> **术语约定**: 本文档及 `methodology/`、`extractors/` 中所有的"书",泛指一切被蒸馏的长内容 — 书籍、长视频转写、播客文字稿、课程、访谈、长文、资料集。
|
||||
|
||||
**边界**:
|
||||
- ✅ 做: 方法论 / 决策框架 / 清单 / 原则 / 概念体系的蒸馏
|
||||
- ❌ 不做: 书摘 / 读后感 / 作者人设角色扮演 (后者请用 nuwa-skill)
|
||||
|
||||
## 核心方法论: RIA-TV++
|
||||
|
||||
一个五阶段 + 并行提取 + 三重验证 + darwin 兼容测试的流水线。详见 `methodology/00-overview.md`。
|
||||
|
||||
```
|
||||
阶段 0: Adler 整书理解 → BOOK_OVERVIEW.md
|
||||
阶段 1: 5 个 agent 并行提取 → 候选方法论单元池
|
||||
阶段 1.5: 三重验证筛选 → 通过的单元 (用户轻确认)
|
||||
阶段 2: RIA++ 构造 skill → 每个 skill 的 SKILL.md
|
||||
阶段 3: Zettelkasten 链接 → INDEX.md + GLOSSARY.md
|
||||
阶段 4: 压力测试 (darwin 兼容) → test-prompts.json + 回炉淘汰
|
||||
阶段 5: 交付 → DIGEST.md 精华长文 + 安装到 skills 目录
|
||||
```
|
||||
|
||||
## 何时调用此 skill
|
||||
|
||||
用户说类似:
|
||||
- "帮我拆《穷查理宝典》"
|
||||
- "把毛选蒸馏成 skill"
|
||||
- "把这个 B 站视频/播客/课程蒸馏成 skill"
|
||||
- "distill this book into skills: <path>"
|
||||
- "我想把这本书的方法论做成可用的 skill"
|
||||
|
||||
## 输入要求
|
||||
|
||||
在开始前**必须**从用户处确认:
|
||||
1. **内容文本来源**: PDF / EPUB / TXT / 字幕文件 / 转写稿路径, 或可访问的纯文本。**不要**在没有文本的情况下"凭记忆"蒸馏 — 宁可停下来问用户要。(视频/播客建议先用 video-downloader 类工具拿到转写文本)
|
||||
2. **内容元信息**: 书籍是"书名 + 作者 + 出版年"; 视频/播客/课程是"标题 + 作者(UP 主/主播/讲者) + 发布时间"。用于目录命名和审计。
|
||||
3. **是否首次试点**: 如果用户是第一次用 cangjie-skill,建议先蒸馏 1 份内容验证流程再批量。
|
||||
|
||||
**非书籍内容的字段映射**: `source_chapter` 等"章节"字段对视频填时间戳或分 P,对播客填集数,对课程填讲次 — 保证可追溯即可。
|
||||
|
||||
## 输出结构
|
||||
|
||||
```
|
||||
books/<book-slug>/
|
||||
├── PIPELINE_STATE.md # 流水线状态: 当前阶段 + 各 skill 进度 (断点续跑用)
|
||||
├── BOOK_OVERVIEW.md # 阶段 0 产出: 主旨/骨架/术语/批判
|
||||
├── verified.md # 阶段 1.5 产出: 通过三重验证的单元 + 判定理由
|
||||
├── INDEX.md # 阶段 3 产出: skill 总览 + 引用图
|
||||
├── GLOSSARY.md # 阶段 3 产出: 全书共享术语词典
|
||||
├── DIGEST.md # 阶段 5 产出: 面向读者的精华长文
|
||||
├── candidates/ # 阶段 1 产出: 原始候选池 (审计用)
|
||||
├── rejected/ # 阶段 1.5 淘汰的单元 + 原因 (审计用)
|
||||
├── <skill-slug-1>/
|
||||
│ ├── SKILL.md
|
||||
│ ├── test-prompts.json # darwin-skill 兼容格式
|
||||
│ └── test-results.md # 阶段 4 测试通过率 + 失败分析
|
||||
├── <skill-slug-2>/
|
||||
│ └── ...
|
||||
```
|
||||
|
||||
## 执行流程 (严格按顺序)
|
||||
|
||||
**断点续跑**: 开始前先检查 `books/<slug>/PIPELINE_STATE.md` 是否存在。存在则读取并从记录的阶段续跑,不要从头重来。每完成一个阶段,更新该文件 (当前阶段 / 已完成产物 / 各 skill 状态 / 下一步),格式用简单的 checklist markdown 即可。
|
||||
|
||||
### 阶段 0 — 整书理解
|
||||
|
||||
1. 读取用户提供的书本文本。大文件分块阅读。
|
||||
2. 执行 `methodology/01-stage0-adler.md` 中的 Adler 四步 (结构 / 解释 / 批判 / 应用)。
|
||||
3. 按 `templates/BOOK_OVERVIEW.md.template` 填充,写入 `books/<slug>/BOOK_OVERVIEW.md`。
|
||||
4. 把产出展示给用户确认:"骨架我理解对了吗?有没有你希望重点突出的方向?" 得到确认再进入阶段 1。
|
||||
|
||||
### 阶段 1 — 5 个 sub-agent 并行提取
|
||||
|
||||
**并行** spawn 5 个 Task sub-agents(使用 Agent 工具,一次调用中发起 5 个):
|
||||
|
||||
| sub-agent | 读取的 prompt | 产出 |
|
||||
|---|---|---|
|
||||
| 框架提取器 | `extractors/framework-extractor.md` | 决策框架 / 思维模型 |
|
||||
| 原则提取器 | `extractors/principle-extractor.md` | 原则 / 清单 / 规则 |
|
||||
| 案例提取器 | `extractors/case-extractor.md` | 作者在书中亲自使用过的实例 |
|
||||
| 反例提取器 | `extractors/counter-example-extractor.md` | 书中警告的失败模式 |
|
||||
| 术语提取器 | `extractors/glossary-extractor.md` | 关键概念词典 |
|
||||
|
||||
每个 sub-agent 独立读书、独立提取、独立输出到 `books/<slug>/candidates/<type>.md`。
|
||||
|
||||
- **长文本**: 超出单个 sub-agent 上下文的内容,按 `methodology/02-stage1-parallel-extract.md` 的分块策略处理。
|
||||
- **降级方案**: 当前环境不支持并行 sub-agent 时,用同样 5 个 extractor prompt **串行**执行,产出格式不变。
|
||||
|
||||
### 阶段 1.5 — 三重验证筛选
|
||||
|
||||
读取 `methodology/03-stage1.5-triple-verify.md`,对每个候选单元执行:
|
||||
|
||||
- **V1 跨域**: 书中至少 2 个独立段落有佐证?
|
||||
- **V2 预测力**: 能用它回答一个书里没明说的新问题吗?
|
||||
- **V3 独特性**: 不是任何聪明人都会说的常识吗?
|
||||
|
||||
通过的写入 `books/<slug>/verified.md`。不通过的写入 `books/<slug>/rejected/` 并附原因 — 保留审计轨迹,也允许用户事后捞回。
|
||||
|
||||
**用户轻确认** ★: 筛选完成后,把"通过的 N 个候选标题 + 淘汰的 M 个"列表展示给用户:"这 N 个会做成 skill,有想捞回或砍掉的吗?" 得到确认再进入阶段 2 — 阶段 2–4 是最耗时的部分,这一步确认能避免大量返工。
|
||||
|
||||
### 阶段 2 — RIA++ 构造 skill
|
||||
|
||||
对每个通过的单元,按 `templates/SKILL.md.template` 填充:
|
||||
|
||||
- **R (Reading)**: 原文引用 ≤150 字/段 (英文原文 ≤100 词/段)
|
||||
- **I (Interpretation)**: 用自己的话重写方法论骨架 (避免照搬译本)
|
||||
- **A1 (Past Application)**: 书中作者用过的案例
|
||||
- **A2 (Future Trigger)** ★: 用户在什么情境下会需要这个 → skill 的 `description` 字段
|
||||
- **E (Execution)**: 1-2-3 可执行步骤
|
||||
- **B (Boundary)**: 什么时候不适用 / 来自阶段 0 批判阶段的作者盲点
|
||||
|
||||
细则见 `methodology/04-stage2-ria-plus.md`。注意: A2 中"与相邻 skill 的区分"此时只写**初稿** (基于 verified.md 的单元列表),阶段 3 建立链接后回填定稿。
|
||||
|
||||
### 阶段 3 — Zettelkasten 链接
|
||||
|
||||
按 `methodology/05-stage3-zettelkasten.md`:
|
||||
1. 找出 skill 之间的引用关系 (A 依赖 B / A 对比 B / A 组合 B)
|
||||
2. 在每个 SKILL.md 末尾补"相关 skills"段,并回填 A2 的"与相邻 skill 的区分"
|
||||
3. 按 `templates/INDEX.md.template` 生成 `INDEX.md` (含引用图 mermaid)
|
||||
4. 把 `candidates/glossary.md` 整理成 `books/<slug>/GLOSSARY.md` — 它是所有 skill 的共享词典,不该埋在审计目录里
|
||||
|
||||
### 阶段 4 — 压力测试 (darwin 兼容)
|
||||
|
||||
对每个 skill 按 `methodology/06-stage4-pressure-test.md`:
|
||||
1. 设计 5–10 条测试 prompt,按 `templates/test-prompts.json.template` 写入 `test-prompts.json`
|
||||
2. 至少包括 3 类: **应调用** / **不应调用 (诱饵)** / **边界模糊**。诱饵中至少 1 条必须是"应触发同书另一个 skill"的场景 (跨 skill 混淆测试)
|
||||
3. 优先用独立 sub-agent 盲测每条 prompt,由主流程对照预期统计结果,**未过的回炉重做阶段 2** — 不做"表面修补"
|
||||
4. 每个 skill 的测试结果写入 `<skill-dir>/test-results.md`
|
||||
|
||||
### 阶段 5 — 交付
|
||||
|
||||
按 `methodology/07-stage5-deliver.md`:
|
||||
1. 生成 `books/<slug>/DIGEST.md` — 面向读者的精华长文 (按 `templates/DIGEST.md.template`),满足"不读全书、只看精华"的需求
|
||||
2. 询问用户安装位置 (用户级 `~/.claude/skills/` 或项目级 `.claude/skills/` / `.cursor/skills/`),把通过测试的 skill 复制或 symlink 过去 — **没有这一步,产出的 skill 无法被真正调用**
|
||||
3. 告知用户: "已完成,可一键喂给 darwin-skill 自动进化"
|
||||
|
||||
## 质量红线 (违反则阻止输出)
|
||||
|
||||
1. 每个 skill 必须通过**全部**三重验证
|
||||
2. 每个 skill 必须有完整的 R / I / A1 / A2 / E / B 六段
|
||||
3. 原文引用 ≤150 字/段 (英文 ≤100 词/段)
|
||||
4. 每个 skill 必须有 `test-prompts.json`,且包含诱饵测试 (不应调用的场景),其中至少 1 条是同书兄弟 skill 的场景
|
||||
5. `description` 字段必须明确 trigger 条件,不能只是"一个关于 X 的 skill"
|
||||
|
||||
## 与 nuwa-skill / darwin-skill 的生态定位
|
||||
|
||||
- **nuwa-skill**: 蒸馏人 (思维方式 / 表达 DNA)
|
||||
- **cangjie-skill** (本 skill): 蒸馏书 (方法论 / 框架 / 原则)
|
||||
- **darwin-skill**: 进化任意 skill
|
||||
|
||||
三者咬合: 本 skill 输出的 `test-prompts.json` 严格遵循 darwin-skill 格式,以便产出的 skill 可直接接入 darwin 做自动进化。
|
||||
|
||||
## 调用惯例
|
||||
|
||||
- **永远先试点 1 本** — 除非用户明确说"批量"
|
||||
- **阶段之间主动汇报进度** — 不要静默跑完再 dump 结果
|
||||
- **不凭记忆拆书** — 没文本就停下来问
|
||||
- **保留审计轨迹** — candidates/ 和 rejected/ 都要留
|
||||
- **随时可续跑** — 每完成一个阶段就更新 PIPELINE_STATE.md,中断后从状态文件恢复
|
||||
@@ -0,0 +1,65 @@
|
||||
# Case Extractor
|
||||
|
||||
你是 cangjie-skill 流水线中**并行运行的 5 个 extractor 之一**,专门负责识别**作者在书中亲自应用某个方法论的具体案例**。
|
||||
|
||||
## 为什么要单独抽案例
|
||||
|
||||
案例本身不独立成 skill,但它们是阶段 1.5 **V1 跨域验证**的关键证据,也是阶段 2 **A1 (Past Application)** 段的素材来源。没有案例池,后面两步都会卡住。
|
||||
|
||||
## 你的输入
|
||||
|
||||
- `BOOK_OVERVIEW.md`
|
||||
- 书本文本
|
||||
|
||||
## 你的职责范围
|
||||
|
||||
- 作者**亲自**经历/操作/决策的真实事件
|
||||
- 作者**转述**的历史事件、他人案例 (但必须是作者用来说明某个方法论的)
|
||||
- 每个案例必须**绑定到一个方法论主题**,否则意义不大
|
||||
|
||||
## 不属于你的
|
||||
|
||||
- 纯背景叙事 (没有方法论绑定)
|
||||
- 虚构的寓言/比喻 (除非作者拿它直接说明方法)
|
||||
- 作者的观点 / 原则 / 框架本身
|
||||
|
||||
## 识别信号
|
||||
|
||||
- "1973 年,我曾..."
|
||||
- "有一次..."
|
||||
- "某某公司的案例..."
|
||||
- "巴菲特告诉我..."
|
||||
- "比如..."
|
||||
- 过去时叙述 + 伴随评论/反思
|
||||
|
||||
## 输出格式
|
||||
|
||||
```yaml
|
||||
- id: c01
|
||||
title: 投资 See's Candy
|
||||
type: case
|
||||
source_chapter: 第 5 讲
|
||||
source_quote: |
|
||||
"我们以 2500 万美元收购了 See's Candy...这是我们第一次为品牌溢价付费。"
|
||||
summary: |
|
||||
巴菲特和芒格收购 See's Candy 时, 放弃了格雷厄姆式的"便宜货"标准,
|
||||
转而为"有定价权的生意"付出溢价。这笔投资后来成了他们转向
|
||||
"优质企业+合理价格"策略的转折点。
|
||||
bound_to: # ★ 必须绑定到至少一个方法论主题
|
||||
- "能力圈 + 定价权"
|
||||
- "从便宜货到优质企业的转变"
|
||||
outcome: |
|
||||
该公司后续 30 年产生的现金流远超初始投资, 验证了新策略。
|
||||
tags: [case, investment, turning-point]
|
||||
```
|
||||
|
||||
## 自检
|
||||
|
||||
- [ ] 每条案例都有 `bound_to` 字段,明确它在阐释什么
|
||||
- [ ] 有原文引用作为证据
|
||||
- [ ] `outcome` 字段尽量填 (如果书中说了结果)
|
||||
- [ ] 不做筛选
|
||||
|
||||
## 数量预期
|
||||
|
||||
传记类 / 访谈整理类的书可能有几十上百个案例。方法论书可能 10–30 个。都不少于 5 个,否则阶段 2 的 A1 段会空。
|
||||
@@ -0,0 +1,67 @@
|
||||
# Counter-Example Extractor
|
||||
|
||||
你是 cangjie-skill 流水线中**并行运行的 5 个 extractor 之一**,专门负责识别**作者警告的失败模式 / 反例 / 陷阱**。
|
||||
|
||||
## 为什么要单独抽反例
|
||||
|
||||
反例是阶段 2 的 **B (Boundary) 段**的核心素材来源。没有反例,skill 就没有边界,会在不该用的时候被调用,反而帮倒忙。**这是 cangjie-skill 区别于普通书摘最重要的一类内容。**
|
||||
|
||||
## 你的输入
|
||||
|
||||
- `BOOK_OVERVIEW.md`
|
||||
- 书本文本
|
||||
|
||||
## 你的职责范围
|
||||
|
||||
- **作者明确警告的失败模式**: "不要 X, 否则..."
|
||||
- **作者批评的错误做法**: "很多人以为 X, 但其实..."
|
||||
- **作者承认自己犯过的错**: "我当年错在..."
|
||||
- **作者描述的反面典型**: "某某公司就是这样失败的..."
|
||||
- **认知偏误 / 心理陷阱**: (芒格类书籍的核心)
|
||||
|
||||
## 不属于你的
|
||||
|
||||
- 一般性的道德批评 (没有可学习的机制)
|
||||
- 作者情绪化的吐槽 (没有论证)
|
||||
|
||||
## 识别信号
|
||||
|
||||
- "最大的错误是..."
|
||||
- "千万不要..."
|
||||
- "很多人以为..."
|
||||
- "失败的原因是..."
|
||||
- "陷阱在于..."
|
||||
- "我当年..." + 悔意
|
||||
- "人们往往..." + 负面
|
||||
|
||||
## 输出格式
|
||||
|
||||
```yaml
|
||||
- id: ce01
|
||||
title: 过度自信偏误
|
||||
type: counter-example
|
||||
source_chapter: 误判心理学 · 第 12 条
|
||||
source_quote: |
|
||||
"大多数人都认为自己比平均水平更聪明、更公正、更有能力。
|
||||
这种自我评价偏误在投资中尤其致命。"
|
||||
failure_mode: |
|
||||
在自己不懂的领域自认为懂, 导致做出超出能力圈的决策。
|
||||
mechanism: |
|
||||
人脑默认把"熟悉"等同于"理解", 把"喜欢"等同于"正确"。
|
||||
没有外部校正机制时, 过度自信会随成功次数累积而强化。
|
||||
warning_signs:
|
||||
- 决策时感到"这很简单"
|
||||
- 没有 plan B
|
||||
- 不愿意向人请教
|
||||
bound_to:
|
||||
- "能力圈判断"
|
||||
- "检查清单决策"
|
||||
tags: [counter-example, cognitive-bias, overconfidence]
|
||||
```
|
||||
|
||||
## 自检
|
||||
|
||||
- [ ] 每条都有 `failure_mode` 和 `mechanism` (不只是说"这是错的")
|
||||
- [ ] `warning_signs` 尽量填 (让后续的 B 段有信号)
|
||||
- [ ] `bound_to`: 说明这个反例会限制哪些正面 skill 的适用范围
|
||||
- [ ] 有原文引用
|
||||
@@ -0,0 +1,61 @@
|
||||
# Framework Extractor
|
||||
|
||||
你是 cangjie-skill 流水线中**并行运行的 5 个 extractor 之一**,专门负责从一本书里识别**思维模型 / 决策框架 / 推理方法**。
|
||||
|
||||
## 你的输入
|
||||
|
||||
- `BOOK_OVERVIEW.md` — 全书骨架 (阶段 0 产出)
|
||||
- 书本文本 (完整或分块)
|
||||
|
||||
## 你的职责范围 (只找这些)
|
||||
|
||||
- **思维模型**: 可迁移的思考结构 (如 "能力圈" / "逆向思维" / "多元思维模型")
|
||||
- **决策框架**: 面对决策时的结构化流程 (如 "先问最坏情况再算期望值")
|
||||
- **推理方法**: 从已知推向未知的特定路径 (如 "从第一性原理出发")
|
||||
|
||||
## 不属于你的 (交给别的 extractor)
|
||||
|
||||
- 原则 / 清单 / 规则 → `principle-extractor`
|
||||
- 作者亲自用过的具体案例 → `case-extractor`
|
||||
- 失败模式 / 反例 / 警告 → `counter-example-extractor`
|
||||
- 术语定义 → `glossary-extractor`
|
||||
|
||||
边界模糊时**宁可多提取**,阶段 1.5 会去重。
|
||||
|
||||
## 识别信号 (在书中看到这些就要警觉)
|
||||
|
||||
- 作者给某个思考方式**起了专门的名字**
|
||||
- 某段话在讲**"面对 X 类问题时应该..."**的通用流程
|
||||
- 作者**反复在不同章节引用同一个思考结构**
|
||||
- 作者明确说"这是我常用的 mental model / 方法 / 原则"
|
||||
- 有结构化的 **if-then / 先-后 / 从-到** 句式
|
||||
|
||||
## 输出格式
|
||||
|
||||
每条候选写成一个 YAML 条目,追加到 `books/<slug>/candidates/frameworks.md`:
|
||||
|
||||
```yaml
|
||||
- id: f01
|
||||
title: 逆向思维
|
||||
type: framework
|
||||
source_chapter: 第 3 讲
|
||||
source_quote: |
|
||||
"反过来想,总是反过来想。如果知道我会在哪里死去,那我就永远不去那里。"
|
||||
summary: |
|
||||
面对一个目标时, 不直接问"怎么达成", 而先问"什么会让我失败"。
|
||||
列出失败因素后, 避免它们, 反向推出应做的事。
|
||||
这比正向推理更有效, 因为人对"不想要什么"的判断通常比对"想要什么"更清晰。
|
||||
tags: [decision, mental-model, inversion]
|
||||
```
|
||||
|
||||
## 自检 (提交前)
|
||||
|
||||
- [ ] 每条都在书中有原文根据,不是脑补
|
||||
- [ ] 每条都是"可迁移的思考结构",而不是具体案例或一句金句
|
||||
- [ ] 原文引用 ≤150 字 (英文 ≤100 词)
|
||||
- [ ] 至少标了 1 个 tag
|
||||
- [ ] **不做筛选** — 宁错杀,交给阶段 1.5 三重验证
|
||||
|
||||
## 数量预期
|
||||
|
||||
方法论密集的书通常有 10–30 个候选框架。少于 5 个很可能你漏读了;多于 50 个你可能把"非框架"的东西也算进来了。
|
||||
@@ -0,0 +1,53 @@
|
||||
# Glossary Extractor
|
||||
|
||||
你是 cangjie-skill 流水线中**并行运行的 5 个 extractor 之一**,专门负责构建**关键概念词典**。
|
||||
|
||||
## 为什么要单独抽术语
|
||||
|
||||
作者**用某个词的方式**往往和字典不一样。如果不统一术语,后面的 skill 会把"能力圈"(芒格的特定用法) 当成字典里的"能力范围"来用,完全失真。
|
||||
|
||||
这个产出不会独立成 skill,但会作为**所有 skill 的共享词典**被引用。
|
||||
|
||||
## 你的输入
|
||||
|
||||
- `BOOK_OVERVIEW.md`
|
||||
- 书本文本
|
||||
|
||||
## 你的职责范围
|
||||
|
||||
挑出满足以下**任一**条件的词:
|
||||
|
||||
1. 作者反复使用 (全书出现 ≥3 次)
|
||||
2. 作者明确定义过 ("所谓 X, 是指...")
|
||||
3. 看起来像常用词但作者用法和常识不一样
|
||||
4. 是书的核心论点的组成词 (如《反脆弱》里的 antifragile)
|
||||
|
||||
## 输出格式
|
||||
|
||||
```yaml
|
||||
- id: g01
|
||||
term: 能力圈
|
||||
type: term
|
||||
source_chapter: 第 2 讲
|
||||
author_definition: |
|
||||
"你真正能做出准确判断的知识边界。不是你知道什么, 而是你知道'你知道什么'和'你不知道什么'的边界。"
|
||||
key_distinction: |
|
||||
≠ "熟悉的领域" — 熟悉不代表能做判断
|
||||
≠ "专业领域" — 博士学位也可能在能力圈外
|
||||
= 能持续做出比市场更准判断的范围 (需经实战验证)
|
||||
why_it_matters: |
|
||||
"能力圈"一词在所有投资决策类 skill 中都会出现。
|
||||
若沿用字典义, skill 会建议用户"评估一下是否熟悉该领域", 这是错的。
|
||||
正确的用法是"评估自己过去在此领域的判断准确率"。
|
||||
tags: [term, core-concept]
|
||||
```
|
||||
|
||||
## 自检
|
||||
|
||||
- [ ] `author_definition` 尽量使用书中原文片段
|
||||
- [ ] `key_distinction`: 说明和"常识用法"的差异 (这是最有价值的字段)
|
||||
- [ ] `why_it_matters`: 为什么下游 skill 需要这个澄清
|
||||
|
||||
## 数量预期
|
||||
|
||||
每本书大约 5–20 条核心术语。多于 30 条说明你把一般词汇也收进来了 — 只挑真正关键的。
|
||||
@@ -0,0 +1,59 @@
|
||||
# Principle Extractor
|
||||
|
||||
你是 cangjie-skill 流水线中**并行运行的 5 个 extractor 之一**,专门负责识别**原则 / 清单 / 规则 / 断言**。
|
||||
|
||||
## 你的输入
|
||||
|
||||
- `BOOK_OVERVIEW.md`
|
||||
- 书本文本
|
||||
|
||||
## 你的职责范围
|
||||
|
||||
- **原则 (principles)**: 作者明确提出的"应该如何" / "不应该如何"的断言
|
||||
- **清单 (checklists)**: 结构化的项目列表 (投资检查清单 / 决策前自问清单)
|
||||
- **规则 (rules)**: 可直接拿来套用的判断规则 (如 "永远不要...当..." / "只有在...时才...")
|
||||
- **格言/箴言 (maxims)**: 作者反复强调、带有行动指导意义的短句
|
||||
|
||||
## 不属于你的
|
||||
|
||||
- 思维模型 / 推理结构 → `framework-extractor`
|
||||
- 作者亲自用过的案例 → `case-extractor`
|
||||
- 反例 / 警告的失败模式 → `counter-example-extractor`
|
||||
- 术语 → `glossary-extractor`
|
||||
|
||||
## 识别信号
|
||||
|
||||
- "必须..." / "不要..." / "要记住..." / "三条原则..."
|
||||
- 编号列表 (1. 2. 3.) 或项目符号
|
||||
- "每当...就要..." / "只有...才能..."
|
||||
- 作者在多个场合重复的同一条断言
|
||||
- 毛选里的 "凡是...都..." / "...必须..."
|
||||
- 段永平的 "stop doing list" 类项目
|
||||
|
||||
## 输出格式
|
||||
|
||||
```yaml
|
||||
- id: p01
|
||||
title: Stop Doing List
|
||||
type: principle
|
||||
source_chapter: 第 2 部分 · 投资篇
|
||||
source_quote: |
|
||||
"不做什么比做什么更重要。我们的 stop doing list 比 to do list 长得多。"
|
||||
summary: |
|
||||
主动列出"绝对不做"的清单, 比列"要做"的清单更能防止重大错误。
|
||||
适用于投资、战略、职业选择等"错一次就伤筋动骨"的场景。
|
||||
tags: [principle, decision, negative-checklist]
|
||||
```
|
||||
|
||||
## 自检
|
||||
|
||||
- [ ] 每条都是"可直接应用的规则",不是思维结构 (后者给 framework-extractor)
|
||||
- [ ] 有明确原文
|
||||
- [ ] 引用 ≤150 字 (英文 ≤100 词)
|
||||
- [ ] 不做筛选
|
||||
|
||||
## 常见错误
|
||||
|
||||
1. **把描述当原则** — "作者告诉我们投资要谨慎" 不是原则;"绝不投资你看不懂的生意" 是。
|
||||
2. **把一整章当一条** — 原则必须原子化,一章可能包含 3–5 条独立原则,要拆开。
|
||||
3. **和 framework 混淆** — framework 是"怎么想",principle 是"做不做"。一个告诉你推理方式,一个告诉你 yes/no。
|
||||
@@ -0,0 +1,83 @@
|
||||
# RIA-TV++ 方法论总览
|
||||
|
||||
本文是 cangjie-skill 所用 SOP 的设计说明,解释"为什么这么做"。执行时的具体步骤请读 `SKILL.md` 和 `methodology/01-*` 至 `07-*`。
|
||||
|
||||
## 命名
|
||||
|
||||
**RIA-TV++** =
|
||||
- **RIA** — 赵周 (《这样读书就够了》) 的便签拆书法: Reading / Interpretation / Appropriation
|
||||
- **TV** — Triple Verification,借自 nuwa-skill 的三重验证
|
||||
- **++** — 面向 agent 执行的扩展: E (Execution 可执行步骤) + B (Boundary 边界)
|
||||
|
||||
## 思想来源
|
||||
|
||||
| 来源 | 借鉴内容 |
|
||||
|---|---|
|
||||
| Mortimer Adler 《如何阅读一本书》 | 阶段 0: 分析阅读三阶段 (结构/解释/批判) |
|
||||
| 赵周 RIA 拆书法 | 阶段 2: R-I-A1-A2 基本骨架, 尤其 A2 → trigger |
|
||||
| Niklas Luhmann Zettelkasten | 原子化 + 链接 + 用自己的话重写 |
|
||||
| Tiago Forte Progressive Summarization | 阶段 4 的"可验证压缩链条"思想 |
|
||||
| nuwa-skill | 阶段 1 并行 extractor + 阶段 1.5 三重验证 |
|
||||
| darwin-skill | 阶段 4 test-prompts.json 格式 + 可进化性 |
|
||||
|
||||
## 根本洞察
|
||||
|
||||
**现有读书方法论都是为人类读者蒸馏,不是为 agent 执行者蒸馏。**
|
||||
|
||||
| 维度 | 给人看 | 给 agent 用 (cangjie-skill 目标) |
|
||||
|---|---|---|
|
||||
| 关键字段 | 故事 / 金句 / 情感钩子 | trigger / 可执行步骤 / 判停标准 |
|
||||
| 失败模式 | 读完就忘 | trigger 不准 → 永不调用或乱调用 |
|
||||
| 成功标准 | 读者"有收获" | 真实问题被解决 |
|
||||
|
||||
所以 RIA-TV++ 的所有"扩展"(TV / E / B / test-prompts) 都是为了解决这个目标迁移带来的新问题。
|
||||
|
||||
## 流水线
|
||||
|
||||
```
|
||||
┌───────────────────┐
|
||||
│ 阶段 0: 整书理解 │ Adler 四步
|
||||
└─────────┬─────────┘
|
||||
│ BOOK_OVERVIEW.md
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 1: 并行提取 │ 5 个 sub-agent 同时跑
|
||||
└─────────┬─────────┘
|
||||
│ candidates/
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 1.5: 三重验证 │ V1 跨域 / V2 预测力 / V3 独特性
|
||||
└─────────┬─────────┘
|
||||
│ 通过单元 + rejected/
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 2: RIA++ 构造 │ R / I / A1 / A2 / E / B
|
||||
└─────────┬─────────┘
|
||||
│ 每个 skill 的 SKILL.md
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 3: 链接 │ Zettelkasten + INDEX.md
|
||||
└─────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 4: 压力测试 │ test-prompts.json + 盲测 + 回炉
|
||||
└─────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌───────────────────┐
|
||||
│ 阶段 5: 交付 │ DIGEST.md 精华长文 + 安装到 skills 目录
|
||||
└───────────────────┘
|
||||
│
|
||||
▼
|
||||
可喂给 darwin-skill 自动进化
|
||||
```
|
||||
|
||||
## 不变量 (任何迭代都不能违反)
|
||||
|
||||
1. **原子性**: 一个 skill 只做一个方法论单元,不能"大而全"
|
||||
2. **可追溯**: 每个 skill 必须有原文引用,指向源书章节 (视频指向时间戳/分 P)
|
||||
3. **可验证**: 每个 skill 必须通过三重验证 + 压力测试
|
||||
4. **可进化**: 每个 skill 必须附带 darwin 兼容的 test-prompts.json
|
||||
5. **用户参与**: 阶段 0 之后必须让用户确认骨架; 阶段 1.5 之后必须让用户确认入选名单
|
||||
6. **可交付**: 流程终点是"用户能调用"— skill 必须被安装到 skills 目录,读者需求由 DIGEST.md 承接
|
||||
@@ -0,0 +1,57 @@
|
||||
# 阶段 0 — 整书理解 (Adler 分析阅读)
|
||||
|
||||
## 目标
|
||||
|
||||
在动手拆书之前,先**真正读懂这本书**。没有这一步,拆出来的 skill 只是一堆金句集,会带上作者的盲点却不自知。
|
||||
|
||||
产出: `books/<slug>/BOOK_OVERVIEW.md` (按 `templates/BOOK_OVERVIEW.md.template` 填充)。
|
||||
|
||||
## 四步 (前三步来自 Adler, 第四步是本 skill 新增)
|
||||
|
||||
### 步骤 1 — 结构 (Structural)
|
||||
|
||||
识别书的"骨架",回答:
|
||||
|
||||
- **这本书属于什么类型?** (方法论 / 传记 / 哲学 / 实操手册 / ...)
|
||||
- **它的主旨用一句话说是什么?** — 必须真的能压缩到一句
|
||||
- **它的主要部分如何组合成一个整体?** — 列出 3–7 个一级论点并标出它们的关系 (并列 / 递进 / 对比 / 反驳)
|
||||
- **作者试图解决的核心问题是什么?**
|
||||
|
||||
### 步骤 2 — 解释 (Interpretive)
|
||||
|
||||
- **关键术语**: 列出作者反复使用、有特定含义的概念词,给每个词写一句"作者本人的用法"定义 (不是字典定义)
|
||||
- **核心命题**: 用你自己的话重述作者的 5–15 个核心主张
|
||||
- **论证链**: 这些主张之间是怎么推导的? 作者用什么证据支撑?
|
||||
|
||||
### 步骤 3 — 批判 (Critical) ★ 最容易被跳过也最重要
|
||||
|
||||
Adler 原话: "在没有找出论证中的错误之前,你不能不同意作者。" 反过来: **在找出作者的局限之前,你也不能完全同意。**
|
||||
|
||||
必须回答:
|
||||
- **作者的时代局限**: 这本书写于什么时期? 哪些前提可能已经不成立?
|
||||
- **作者的立场盲点**: 作者的身份 / 行业 / 文化背景让他忽略了什么?
|
||||
- **未被证明的假设**: 作者把什么当成了不言自明但其实需要论证的东西?
|
||||
- **反对意见**: 如果有人要反驳这本书,最强的论点会是什么?
|
||||
|
||||
这一步的产出会直接成为每个 skill 的 **Boundary (B)** 字段来源。
|
||||
|
||||
### 步骤 4 — 应用潜力 (Applicability, 本 skill 新增)
|
||||
|
||||
- **哪些内容可以 skill 化?** — 框架 / 清单 / 原则 / 决策程序
|
||||
- **哪些内容不适合 skill 化?** — 纯史料 / 纯故事 / 纯情感 (但可作为其他 skill 的 example)
|
||||
- **预估 skill 数量**: 给一个粗略区间 (不要硬凑)
|
||||
- **预估优先级**: 从"最能赋能普通人"的角度给候选 skill 排序
|
||||
|
||||
## 质量门 (进入阶段 1 之前必须满足)
|
||||
|
||||
- [ ] 主旨能用一句话说清
|
||||
- [ ] 骨架列出 3–7 个一级论点
|
||||
- [ ] 关键术语词典有 ≥5 条
|
||||
- [ ] 批判阶段至少列出 3 条作者局限 (这一步没做到位就不能继续)
|
||||
- [ ] 已向用户展示 BOOK_OVERVIEW.md 并得到确认
|
||||
|
||||
## 常见失败模式
|
||||
|
||||
1. **跳过批判阶段** — 导致 skill 把作者的偏见当真理
|
||||
2. **骨架不是"作者的骨架",而是自己的想法** — 注意你在写摘要还是在写读后感
|
||||
3. **术语定义用字典 / 常识而非作者的特定用法** — 作者用"能力圈"和字典用"能力圈"不是一回事
|
||||
@@ -0,0 +1,69 @@
|
||||
# 阶段 1 — 5 个 sub-agent 并行提取
|
||||
|
||||
## 目标
|
||||
|
||||
不用单一视角读一遍,而是**同时从 5 个不同角度扫描全书**,最大化候选单元覆盖率。
|
||||
|
||||
## 为什么要并行
|
||||
|
||||
- **覆盖**: 单一视角会漏。框架提取器找不到的"反例",反例提取器会找到。
|
||||
- **速度**: Claude Code 的 Agent 工具支持并行,不用白不用。
|
||||
- **独立性**: 每个 extractor 独立判断,避免互相污染 — 三重验证才能真正起作用 (V1 跨域要求"独立出现")
|
||||
|
||||
## 5 个 sub-agent
|
||||
|
||||
每个 sub-agent 接收:
|
||||
- `BOOK_OVERVIEW.md` (阶段 0 产出, 提供全局上下文)
|
||||
- 书本文本 (或文本路径)
|
||||
- 对应的 extractor prompt (`extractors/<type>-extractor.md`)
|
||||
|
||||
并在一次调用中通过 Agent 工具 **同时 spawn 5 个**,不是串行。
|
||||
|
||||
**降级方案**: 当前环境不支持并行 sub-agent 时,用同样 5 个 extractor prompt 串行执行 (每次以"干净视角"执行一个 extractor 的职责,不带上一个 extractor 的判断),产出格式不变。
|
||||
|
||||
## 长文本分块策略 (超出单个 sub-agent 上下文时)
|
||||
|
||||
一本大部头 (如全五卷选集) 或几小时视频的转写稿,可能超出单个 sub-agent 能一次读完的上下文。此时:
|
||||
|
||||
1. **切块**: 按章节/卷/分 P 等自然边界切块,每块控制在 sub-agent 能连同 `BOOK_OVERVIEW.md` 一起舒适读完的规模 (经验值: 单块 ≤5 万字)
|
||||
2. **全局锚点**: 每一块都必须附带 `BOOK_OVERVIEW.md` — 它是 extractor 判断"这段内容在全书中扮演什么角色"的锚点,不能省
|
||||
3. **逐块扫描**: extractor 逐块提取候选,标注每条候选来自哪一块 (source_chapter 字段天然承载)
|
||||
4. **块间汇总**: 全部块扫完后,extractor 自己先做一轮合并 — 同一方法论在多块中出现的,合并成一条并保留所有出处 (这些多出处恰好是阶段 1.5 V1 跨域验证的证据)
|
||||
5. 汇总后的结果才写入 `candidates/<type>.md`
|
||||
|
||||
| # | extractor | 查找对象 | 产出文件 |
|
||||
|---|---|---|---|
|
||||
| 1 | framework-extractor | 思维模型 / 决策框架 / 推理方法 | `candidates/frameworks.md` |
|
||||
| 2 | principle-extractor | 原则 / 清单 / 规则 / 断言 | `candidates/principles.md` |
|
||||
| 3 | case-extractor | 作者在书中亲自使用的实例 | `candidates/cases.md` |
|
||||
| 4 | counter-example-extractor | 作者警告的失败 / 反例 / 陷阱 | `candidates/counter-examples.md` |
|
||||
| 5 | glossary-extractor | 关键概念词典 | `candidates/glossary.md` |
|
||||
|
||||
## 每个候选单元的最小字段
|
||||
|
||||
无论是哪个 extractor,产出的每条候选单元必须包含:
|
||||
|
||||
```yaml
|
||||
id: f01 # 类型缩写 + 序号
|
||||
title: 逆向思维 # 简短标题
|
||||
type: framework # framework / principle / case / counter-example / term
|
||||
source_chapter: 第三讲 # 书中位置
|
||||
source_quote: | # 原文引用 ≤150 字 (英文 ≤100 词)
|
||||
"反过来想,总是反过来想..."
|
||||
summary: | # 用自己的话,5-10 行
|
||||
...
|
||||
tags: [decision, mental-model] # 便于后续链接
|
||||
```
|
||||
|
||||
## 输出前的自检
|
||||
|
||||
每个 extractor 在提交候选之前自问:
|
||||
1. 这个单元**在书中**有明确根据吗? (不是我脑补)
|
||||
2. 它属于我这个 extractor 的职责范围吗? (不要越界)
|
||||
3. 它是不是已经在别处被别的 extractor 提取过了? (重复不是问题,阶段 1.5 会合并)
|
||||
|
||||
## 不在本阶段做的事
|
||||
|
||||
- **不做筛选** — 宁错杀,留给阶段 1.5 三重验证
|
||||
- **不写 skill** — 只出候选,不出 SKILL.md
|
||||
- **不做跨单元链接** — 留给阶段 3
|
||||
@@ -0,0 +1,84 @@
|
||||
# 阶段 1.5 — 三重验证筛选
|
||||
|
||||
## 目标
|
||||
|
||||
从候选单元池里,筛出**真正值得做成独立 skill 的方法论单元**。通不过的降级为 example / 引用 / 术语,但不独立成 skill。
|
||||
|
||||
这是 cangjie-skill 区别于"书摘工具"的核心质量门。
|
||||
|
||||
## 三重验证 (全部通过才录取)
|
||||
|
||||
### V1 — 跨域验证 (Cross-domain)
|
||||
|
||||
**问题**: 这个单元在书中**至少 2 个独立的语境**下有佐证吗?
|
||||
|
||||
- "独立"的含义: 不是同一个案例换个说法,而是两个不同的故事/不同的章节/不同的对象都在讲同一个道理
|
||||
- **通过**: 《穷查理宝典》中"逆向思维"在投资决策、避免灾难、教学方法三个独立场景中都出现 → 通过
|
||||
- **不通过**: 某个漂亮句子只在一章里出现过一次,没有书内的独立证据 → 降级为金句 example
|
||||
|
||||
**为什么**: 在多个语境中反复出现的,才是作者真正想传达的稳定方法论,而不是一时兴起的表达。
|
||||
|
||||
### V2 — 预测力测试 (Predictive Power)
|
||||
|
||||
**问题**: 能用这个单元,推导出书里没明说的某个问题的答案吗?
|
||||
|
||||
- 自己设计一个书中没直接讨论过的场景
|
||||
- 尝试用这个方法论去分析它
|
||||
- **通过**: 能得出一个有意义、非平庸的结论 → 通过
|
||||
- **不通过**: 只能得出"努力就会成功"之类的废话 → 这个单元没有真正的解释力,降级
|
||||
|
||||
**为什么**: 真正的方法论必须有**外推能力**。如果它只能复述书里的例子,它是描述不是方法。
|
||||
|
||||
### V3 — 独特性检验 (Exclusivity)
|
||||
|
||||
**问题**: 这个单元是否是"任何聪明人都会说的常识"?
|
||||
|
||||
- 如果把作者名字抹掉,一个对书本领域毫无了解的聪明人也能说出来 → 不通过
|
||||
- 必须是作者**独特视角 / 反直觉见解 / 独特术语体系** → 通过
|
||||
- **通过**: 段永平的"stop doing list" — 主动列出不做什么,反常识 → 通过
|
||||
- **不通过**: "要尊重时间" — 太常识了,没人需要一个 skill 来告诉自己这个
|
||||
|
||||
**为什么**: 常识不需要 skill 承载,Claude 本身就知道。只有作者的**差异化见解**才值得固化成 skill。
|
||||
|
||||
## 验证执行流程
|
||||
|
||||
1. 把阶段 1 的 5 个 candidates/*.md 合并成一个总候选池
|
||||
2. 去重: 同一方法论被多个 extractor 提取的,合并成一条
|
||||
3. 对每条候选跑 V1 / V2 / V3,记录判断和理由
|
||||
4. 通过的,写入 `books/<slug>/verified.md`
|
||||
5. 未通过的,写入 `books/<slug>/rejected/<id>.md`,**必须写明不通过的是哪一项、原因是什么** (审计价值)
|
||||
6. **用户轻确认** ★: 把"通过的 N 个候选标题 + 淘汰的 M 个"展示给用户,问一句"这 N 个会做成 skill,有想捞回或砍掉的吗?" 得到确认再进入阶段 2 — 阶段 2–4 是全流程最耗时的部分,这一句话的成本能避免大量返工
|
||||
|
||||
## 输出模板 (verified.md 单条)
|
||||
|
||||
```yaml
|
||||
id: f01
|
||||
title: 逆向思维
|
||||
type: framework
|
||||
V1_cross_domain:
|
||||
passed: true
|
||||
evidence:
|
||||
- 第 3 讲: 投资决策场景
|
||||
- 第 7 讲: 工程设计场景
|
||||
- 第 11 讲: 教学方法场景
|
||||
V2_predictive_power:
|
||||
passed: true
|
||||
novel_question: "如果面试官问我一个不知道答案的问题该怎么办?"
|
||||
derived_answer: "逆问'我最不希望他认为我是什么样的人',从这个反面倒推应该展现什么"
|
||||
V3_exclusivity:
|
||||
passed: true
|
||||
why_not_common: "常识是'要多想',逆向思维是'优先反着想' — 这是反直觉的排序"
|
||||
→ 进入阶段 2
|
||||
```
|
||||
|
||||
## 常见失败模式
|
||||
|
||||
1. **V1 作弊** — 把同一例子换个说法算两处。要求: 必须是不同章节 + 不同对象 + 不同结论。
|
||||
2. **V2 作弊** — 用一个其实书里讨论过的类似问题冒充"新问题"。要求: 新问题应该让人第一眼不知道书里怎么说。
|
||||
3. **V3 过松** — 只要"说得比较文雅"就认为不是常识。要求: 看**内容**本身是否反直觉,而不是措辞。
|
||||
|
||||
## 数量预期
|
||||
|
||||
经验上,一本方法论密集的书 (如《穷查理宝典》) 通过率约 30–50%。一本散文类书可能只有 5–10%。通过率过低 (<5%) 或过高 (>80%) 都要警惕:
|
||||
- 过低: extractor 可能质量差,要重跑
|
||||
- 过高: 验证标准可能太松
|
||||
@@ -0,0 +1,90 @@
|
||||
# 阶段 2 — RIA++ 构造 skill
|
||||
|
||||
## 目标
|
||||
|
||||
把阶段 1.5 通过的每个方法论单元,构造成一个符合 Claude Code skill 规范的 SKILL.md。
|
||||
|
||||
使用模板: `templates/SKILL.md.template`
|
||||
|
||||
## RIA++ 六段
|
||||
|
||||
### R — Reading (原文)
|
||||
|
||||
- 直接引用 ≤150 字 (英文原文 ≤100 词)
|
||||
- 必须标注出处 (章节 / 页码 / 段落标识; 视频填时间戳或分 P, 播客填集数)
|
||||
- 若原书是英文,引用英文原文 + 你自己翻译的中文,**不要用现成译本** (避免译者版权 + 译本可能失真)
|
||||
|
||||
### I — Interpretation (自述)
|
||||
|
||||
- 用**你自己的话**重写方法论的核心骨架
|
||||
- 5–15 行
|
||||
- 检查: 读完这段,一个没读过原书的人能否理解这个方法论在做什么? 若不能,重写。
|
||||
- 禁止: 照搬原文句子 / 堆砌修辞
|
||||
|
||||
### A1 — Past Application (书中案例)
|
||||
|
||||
- 作者在书中**亲自**用这个方法论处理过的具体案例
|
||||
- 至少 1 条,≤3 条
|
||||
- 每条要点明: 遇到什么问题 → 怎么用这个方法论 → 得出什么结论 → 实际结果如何
|
||||
|
||||
这一段的作用是让 skill 在被调用时,agent 有具体的类比素材可用。
|
||||
|
||||
### A2 — Future Trigger ★ (最关键)
|
||||
|
||||
**这决定了 skill 是否真的会被用起来。**
|
||||
|
||||
必须明确:
|
||||
1. **用户会在什么情境下遇到这类问题?** (场景描述, 3–5 条)
|
||||
2. **这些情境的语言信号是什么?** (用户会说什么样的话)
|
||||
3. **和哪些相邻 skill 不同?** (避免和其他 skill 互相抢调用)
|
||||
|
||||
A2 的产出直接写入 skill frontmatter 的 `description` 字段 — Claude 据此决定是否激活 skill。
|
||||
|
||||
注意:
|
||||
- "与相邻 skill 的区分"在本阶段只写**初稿** (依据 verified.md 的单元列表推测),阶段 3 建立链接关系后回填定稿 — 不要在本阶段硬编相邻关系。
|
||||
- 语言信号建议**中英双写**关键 trigger 词 (用户可能用英文提问,纯中文 description 会降低触发准确率)。
|
||||
|
||||
**好的 A2 示例** (来自"逆向思维" skill):
|
||||
> 用户在纠结一个决策、列举正面理由却理不出头绪时;或在问"怎么做 X 才能成功"时;不适用于纯信息查询类问题。
|
||||
|
||||
**坏的 A2 示例**:
|
||||
> 用户需要思考时。 ← 太宽泛,会误激活
|
||||
|
||||
### E — Execution (可执行步骤)
|
||||
|
||||
- 把方法论转成 1-2-3 步骤
|
||||
- 每一步有**可判断的完成标准**
|
||||
- 如果有判停点 (step 2 之后若 X 则跳到 step 5),显式写出
|
||||
|
||||
E 的作用是让 agent 在调用这个 skill 时有明确的执行路径,不是"自由发挥"。
|
||||
|
||||
### B — Boundary (边界)
|
||||
|
||||
- 什么时候**不要**使用这个 skill (反场景)
|
||||
- 作者在书里警告过的失败模式
|
||||
- 来自阶段 0 批判阶段的作者盲点
|
||||
- 与之相邻但容易混淆的其他方法论
|
||||
|
||||
B 的作用是**防止乱调用**。没有 B 的 skill,会在不该用的时候被用,反而帮倒忙。
|
||||
|
||||
## Frontmatter 设计
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: <skill-slug> # kebab-case, 唯一
|
||||
description: | # A2 的浓缩版, ≤300 字
|
||||
<何时用 + 何时不用 + 关键 trigger>
|
||||
source_book: 《穷查理宝典》 查理·芒格
|
||||
source_chapter: 第三讲
|
||||
tags: [decision, mental-model, cognitive-bias]
|
||||
related_skills: [] # 阶段 3 填充
|
||||
---
|
||||
```
|
||||
|
||||
## 常见失败模式
|
||||
|
||||
1. **I 段写成书摘** — 如果读起来像"本章作者说了 X",你在抄书不是在解释。重写。
|
||||
2. **A2 太宽** — "需要决策时" 这种 trigger 永远不会被精准调用。必须给出**可识别的语言信号**。
|
||||
3. **E 段只有哲学没有动作** — "保持客观" 不是 step,"列出 3 个最不希望发生的结果" 才是。
|
||||
4. **缺 B 段** — 没边界的 skill 会被过度调用,最终用户失望。
|
||||
5. **从 I 直接跳到 E,跳过 A1** — 丢失了"作者亲自用过"的证据,skill 失去权威性。
|
||||
@@ -0,0 +1,46 @@
|
||||
# 阶段 3 — Zettelkasten 链接 + INDEX
|
||||
|
||||
## 目标
|
||||
|
||||
把原子 skill 之间的关系显式化,形成一个可导航的网络,而不是一堆孤立文件。
|
||||
|
||||
## 三类关系
|
||||
|
||||
1. **依赖 (depends-on)**: A 的使用前提是先理解 B
|
||||
- 例: "检查清单决策" 依赖 "多元思维模型" (因为清单的项来自模型)
|
||||
|
||||
2. **对比 (contrasts-with)**: A 和 B 是两种可选方案,看情境选一
|
||||
- 例: "正向推理" 对比 "逆向思维"
|
||||
|
||||
3. **组合 (composes-with)**: A 和 B 经常配合使用
|
||||
- 例: "能力圈判断" 组合 "安全边际"
|
||||
|
||||
## 执行步骤
|
||||
|
||||
1. 列出阶段 2 产出的所有 skill
|
||||
2. 两两扫描,识别是否存在上述三类关系
|
||||
3. 在每个 skill 的 frontmatter `related_skills` 字段填入:
|
||||
```yaml
|
||||
related_skills:
|
||||
- slug: multi-mental-models
|
||||
relation: depends-on
|
||||
- slug: forward-reasoning
|
||||
relation: contrasts-with
|
||||
```
|
||||
4. 在每个 skill 的 SKILL.md 末尾追加"相关 skills"段,用自然语言说明关系
|
||||
5. **回填 A2**: 链接关系确定后,回到每个 skill 的 A2 段,把阶段 2 留下的"与相邻 skill 的区分"初稿改成定稿 (同时同步 frontmatter `description`)
|
||||
6. 生成 `books/<slug>/INDEX.md` (模板 `templates/INDEX.md.template`)
|
||||
7. 把 `candidates/glossary.md` 整理提升为 `books/<slug>/GLOSSARY.md` — 它是所有 skill 共享的术语词典,应在产出根目录可见,而不是埋在审计目录里; INDEX.md 中链接它
|
||||
|
||||
## INDEX.md 必须包含
|
||||
|
||||
- 书的基本信息 (作者/年份/一句话主旨)
|
||||
- 所有 skill 的列表,按主题分组
|
||||
- 引用图 (mermaid flowchart 或 graph)
|
||||
- 推荐学习顺序 (从依赖关系推出)
|
||||
|
||||
## 节制原则
|
||||
|
||||
**不要硬造关系**。如果两个 skill 之间没有真正的依赖/对比/组合关系,就不要写 related_skills。宁可稀疏也不要制造虚假链接。
|
||||
|
||||
一个经验值: 一本书拆出 10 个 skill,合理的关系数大约是 8–15 条。低于 5 条说明拆得太独立 (可能单元选得不对),高于 25 条说明在硬凑关系。
|
||||
@@ -0,0 +1,97 @@
|
||||
# 阶段 4 — 压力测试 (darwin 兼容)
|
||||
|
||||
## 目标
|
||||
|
||||
在 skill 真正交付之前,用一批测试 prompt 验证它**被调用的精准度**和**被调用后的输出质量**。
|
||||
|
||||
不通过的必须回炉 — 不是表面修补 `description` 字段,而是重做阶段 2 的 A2 / E / B。
|
||||
|
||||
## 为什么必须做
|
||||
|
||||
A2 (trigger) 是拆书里最难的环节。一个 skill 做得再漂亮,trigger 不准就等于不存在。压力测试是**唯一**能在发布前发现 trigger 问题的方法。
|
||||
|
||||
## 评测原则: 独立 sub-agent 盲测优先
|
||||
|
||||
压力测试要尽量模拟真实调用: 一个没有参与蒸馏过程、看不到预期答案的 agent,面对用户 prompt 时是否会自然激活这个 skill。
|
||||
|
||||
优先做法:
|
||||
- 对每条测试 prompt 启动一个干净的 sub-agent,或在资源有限时对同一个 skill 的一组 prompt 启动一个干净 sub-agent
|
||||
- 只给 sub-agent: skill 路径或 skill 内容、用户 prompt、可选的相邻 skill 列表
|
||||
- 不给 sub-agent: `type`、`expected_behavior`、`notes`、通过标准、主流程的判断
|
||||
- 要求 sub-agent 输出: `would_trigger`、`reason`、`if_triggered_action`
|
||||
- 主流程再把 sub-agent 输出和 `test-prompts.json` 的预期逐条对比,统计通过率
|
||||
|
||||
如果当前环境没有 sub-agent 能力,才退回到主流程自测,并在 `test-results.md` 里标明这是 fallback 结果,可信度低于独立 sub-agent 盲测。
|
||||
|
||||
## test-prompts.json 格式 (darwin-skill 兼容)
|
||||
|
||||
```json
|
||||
{
|
||||
"skill": "inversion-thinking",
|
||||
"version": "0.1.0",
|
||||
"test_cases": [
|
||||
{
|
||||
"id": "should-trigger-01",
|
||||
"type": "should_trigger",
|
||||
"prompt": "我要决定要不要接这个新项目,列了一堆好处但还是没底",
|
||||
"expected_behavior": "调用 inversion-thinking, 反问'最不希望发生什么'",
|
||||
"notes": "正面场景: 决策纠结"
|
||||
},
|
||||
{
|
||||
"id": "should-not-trigger-01",
|
||||
"type": "should_not_trigger",
|
||||
"prompt": "帮我查一下这个 API 的参数",
|
||||
"expected_behavior": "纯信息查询, 不应调用任何决策 skill",
|
||||
"notes": "诱饵: 非决策场景"
|
||||
},
|
||||
{
|
||||
"id": "edge-01",
|
||||
"type": "edge_case",
|
||||
"prompt": "我在想晚饭吃什么",
|
||||
"expected_behavior": "日常琐事, 不应调用 (虽然字面是'决策')",
|
||||
"notes": "边界: 区分严肃决策和日常选择"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 三类测试缺一不可
|
||||
|
||||
| 类型 | 数量 | 目的 |
|
||||
|---|---|---|
|
||||
| `should_trigger` | 3–5 条 | 该调用时是否调用 |
|
||||
| `should_not_trigger` (诱饵) | 2–3 条 | 不该调用时是否忍住 |
|
||||
| `edge_case` | 1–3 条 | 边界模糊场景的判断是否合理 |
|
||||
|
||||
**没有诱饵测试的 skill 一律打回**。因为只测 positive case,skill 总会看起来"很好",但实际部署后会乱激活。
|
||||
|
||||
**跨 skill 混淆测试 (硬性要求)**: 诱饵中至少 1 条必须是"应该触发同书另一个 skill"的 prompt。同一本书拆出的 10+ 个 skill 之间互相抢调用,是部署后最常见的真实故障 — 只测"完全无关的场景"发现不了它。盲测时把整包所有 skill 的 name + description 列表给 sub-agent,让它做"该激活哪一个"的选择题,而不只是"要不要激活这一个"的判断题。
|
||||
|
||||
## 执行流程
|
||||
|
||||
1. 对每个 skill,按模板写 `test-prompts.json`
|
||||
2. 对每个 test_case 做独立盲测: 隐藏 `type` / `expected_behavior` / `notes`,让 sub-agent 判断"是否会调用这个 skill",记录判断和理由
|
||||
3. 主流程对照 `test-prompts.json` 判卷:
|
||||
- `should_trigger`: sub-agent 应明确调用该 skill,且执行动作符合 `expected_behavior`
|
||||
- `should_not_trigger`: sub-agent 不应调用该 skill,诱饵测试容错为 0
|
||||
- `edge_case`: sub-agent 的判断要符合 `expected_behavior` 中定义的边界理由
|
||||
4. 统计通过率:
|
||||
- **100% 通过** → 接受
|
||||
- **≥80% 通过** → 分析失败 case, 决定是修 A2 还是修测试 (但修测试要警惕自我合理化)
|
||||
- **<80% 通过** → **必须回炉重做阶段 2**,不是小修
|
||||
5. 修复后重新跑,直到通过
|
||||
|
||||
## 判断"修 skill 还是修测试"
|
||||
|
||||
- 如果失败的 case 暴露了 skill **trigger 描述有歧义**: 修 skill
|
||||
- 如果失败的 case 是一个你**之前没想到的合理场景**: 可能需要修 skill 以覆盖或明确排除
|
||||
- 如果失败的 case 是你**为了凑诱饵而设计过狠的场景**: 修测试 (但必须记录理由)
|
||||
|
||||
## 输出
|
||||
|
||||
- `<skill-dir>/test-prompts.json` — darwin 兼容格式
|
||||
- `<skill-dir>/test-results.md` — 本次测试的通过率和失败分析 (审计用)
|
||||
|
||||
## 下一步
|
||||
|
||||
所有 skill 全部通过后,进入阶段 5 (交付),见 `07-stage5-deliver.md`: 生成面向读者的 DIGEST.md 精华长文,并把 skill 安装到用户的 skills 目录 — 之后才向用户提 darwin-skill 自动进化。
|
||||
@@ -0,0 +1,64 @@
|
||||
# 阶段 5 — 交付 (DIGEST + 安装)
|
||||
|
||||
## 目标
|
||||
|
||||
把流水线的产出真正送到两类使用者手里:
|
||||
|
||||
1. **Agent** — skill 必须被安装到宿主环境的 skills 目录,否则永远不会被调用
|
||||
2. **人类读者** — 用一篇 `DIGEST.md` 精华长文承接"不想读全书,但想看精华"的需求
|
||||
|
||||
这两件事都不做,前面五个阶段的产出就只是一堆躺在仓库里的文件。
|
||||
|
||||
## 第 1 步 — 生成 DIGEST.md (面向读者的精华长文)
|
||||
|
||||
### 为什么放在最后而不是阶段 0
|
||||
|
||||
阶段 0 的 `BOOK_OVERVIEW.md` 是**流水线的全局上下文**,会被喂给每个 sub-agent — 它必须精炼,不能为了可读性加长。而 DIGEST 面向人类读者,放在流程终点写,手里的材料最全:
|
||||
|
||||
- `BOOK_OVERVIEW.md` — 骨架 / 术语 / 批判
|
||||
- `verified.md` — 通过三重验证的方法论 (已经筛掉了水分)
|
||||
- 各 skill 的 SKILL.md — 每个方法论的解释 / 案例 / 边界
|
||||
- `candidates/cases.md` / `counter-examples.md` — 案例池和反例池
|
||||
- `GLOSSARY.md` — 术语词典
|
||||
|
||||
**DIGEST 是"蒸馏后的再呈现",不是"重新摘要"** — 它只写通过了验证的内容,所以浓度天然高于普通书摘。
|
||||
|
||||
### 篇幅与结构要求
|
||||
|
||||
- **篇幅**: 5000–10000 字 (视内容体量伸缩; 一篇 20 分钟视频不必硬凑 5000 字)
|
||||
- **组织**: 按书的骨架 (BOOK_OVERVIEW 的一级论点) 组织章节,不按 skill 列表组织 — 读者要的是"这本书讲了什么",不是产物清单
|
||||
- 每个核心方法论写一小节: 它解决什么问题 → 核心逻辑 → 书中最有代表性的案例 → 什么时候会失效
|
||||
- 必须包含**反例/陷阱**一节 (来自 counter-examples) 和**作者的局限**一节 (来自阶段 0 批判) — 只报喜不报忧的精华是软文,不是蒸馏
|
||||
- 每个方法论小节末尾链接对应的 skill 目录,读者想深入时有路径
|
||||
- 允许适量引用原文金句 (每段引用遵守 ≤150 字 / 英文 ≤100 词)
|
||||
|
||||
模板: `templates/DIGEST.md.template`,输出到 `books/<slug>/DIGEST.md`。
|
||||
|
||||
### 质量自检
|
||||
|
||||
- [ ] 一个没读过原书的人,读完 DIGEST 能复述这本书的主旨、3 个以上核心方法论、2 个以上陷阱
|
||||
- [ ] 没有出现"未通过三重验证"的内容被当作核心方法论呈现
|
||||
- [ ] 有批判/局限部分,不是全程吹捧
|
||||
- [ ] 每个方法论小节都有 skill 链接
|
||||
|
||||
## 第 2 步 — 安装 skill 到宿主环境
|
||||
|
||||
产出目录 `books/<slug>/<skill-slug>/` 只是构建产物,宿主 (Claude Code / Cursor 等) 不会从这里加载 skill。必须安装:
|
||||
|
||||
1. **问用户装哪里** (一次性问清,不要逐个 skill 问):
|
||||
- 用户级: `~/.claude/skills/<skill-slug>/` (所有项目可用)
|
||||
- 项目级: `<project>/.claude/skills/<skill-slug>/` 或 `.cursor/skills/<skill-slug>/`
|
||||
- 用户也可能只想要仓库形式 (发布到 GitHub),那就跳过安装
|
||||
2. **只安装通过阶段 4 测试的 skill** — 未通过的留在构建目录里回炉
|
||||
3. 复制 (或 symlink) 整个 skill 目录,含 `SKILL.md` 和 `test-prompts.json`
|
||||
4. 安装后抽 1–2 个 skill 用一句 should_trigger 的 prompt 验证宿主能加载并触发
|
||||
|
||||
## 第 3 步 — 收尾汇报
|
||||
|
||||
告诉用户:
|
||||
|
||||
> 已完成。产出: N 个 skill (已安装到 <位置>)、INDEX.md、GLOSSARY.md、DIGEST.md (精华长文,约 X 字)。
|
||||
> 如需持续进化,可以喂给 darwin-skill: `darwin evolve books/<slug>/`
|
||||
> 它会用这里的 test-prompts.json 做 ratcheting 自动进化。
|
||||
|
||||
最后把 `PIPELINE_STATE.md` 标记为全部完成。
|
||||
@@ -0,0 +1,102 @@
|
||||
# {{BOOK_TITLE}} — 整书理解 (阶段 0 产出)
|
||||
|
||||
> 本文档是 cangjie-skill 流水线的阶段 0 产出, 后续所有 extractor 和 skill 都以此为全局上下文。
|
||||
|
||||
## 基本信息
|
||||
|
||||
- **标题**: {{BOOK_TITLE}}
|
||||
- **作者**: {{AUTHOR}} <!-- 视频填 UP 主/讲者, 播客填主播 -->
|
||||
- **出版/发布时间**: {{YEAR}}
|
||||
- **内容类型**: {{ 书籍 / 视频转写 / 播客 / 课程 / 访谈 / 长文 }}
|
||||
- **版本来源**: {{SOURCE_FILE}}
|
||||
- **处理时间**: {{DATE}}
|
||||
|
||||
---
|
||||
|
||||
## 1. 结构 (Structural)
|
||||
|
||||
### 类型
|
||||
{{ 方法论 / 传记 / 哲学 / 实操手册 / ... }}
|
||||
|
||||
### 一句话主旨
|
||||
{{ 用一句话说清这本书在讲什么, 必须真的是一句 }}
|
||||
|
||||
### 骨架 (主要论点及其关系)
|
||||
|
||||
1. {{论点 1}}
|
||||
2. {{论点 2}}
|
||||
3. {{论点 3}}
|
||||
...
|
||||
|
||||
**论点之间的关系**: {{ 并列 / 递进 / 对比 / 反驳 / 层层深入 }}
|
||||
|
||||
### 作者要解决的核心问题
|
||||
{{ 作者写这本书是为了回答什么问题 }}
|
||||
|
||||
---
|
||||
|
||||
## 2. 解释 (Interpretive)
|
||||
|
||||
### 关键术语 (作者本人的用法)
|
||||
|
||||
| 术语 | 作者的定义 | 和常识用法的差异 |
|
||||
|---|---|---|
|
||||
| {{term}} | {{author's definition}} | {{what's different}} |
|
||||
|
||||
### 核心命题 (用自己的话)
|
||||
|
||||
1. {{命题 1}}
|
||||
2. {{命题 2}}
|
||||
...
|
||||
|
||||
### 论证链
|
||||
{{ 作者用什么证据/论证路径把这些命题串起来 }}
|
||||
|
||||
---
|
||||
|
||||
## 3. 批判 (Critical) ★
|
||||
|
||||
### 作者的时代局限
|
||||
- {{ ... }}
|
||||
|
||||
### 作者的立场盲点
|
||||
- {{ ... }}
|
||||
|
||||
### 未被证明的假设
|
||||
- {{ ... }}
|
||||
|
||||
### 最强反对意见
|
||||
{{ 如果有人要反驳这本书, 最强的论点会是什么 }}
|
||||
|
||||
> **以上批判会直接成为下游 skill 的 Boundary (B) 字段来源**
|
||||
|
||||
---
|
||||
|
||||
## 4. 应用潜力 (Applicability)
|
||||
|
||||
### 可 skill 化的内容
|
||||
- [ ] {{候选主题 1}}
|
||||
- [ ] {{候选主题 2}}
|
||||
...
|
||||
|
||||
### 不适合 skill 化的内容
|
||||
- {{ 这些内容会作为 example / 引用保留, 但不独立成 skill }}
|
||||
|
||||
### 预估 skill 数量
|
||||
**约 {{N}} 个** (最终由阶段 1.5 三重验证决定, 这里只是粗估)
|
||||
|
||||
### 优先级排序 (按"最能赋能普通人"的角度)
|
||||
1. {{top priority}}
|
||||
2. {{...}}
|
||||
|
||||
---
|
||||
|
||||
## ✅ 质量门检查
|
||||
|
||||
- [ ] 主旨能用一句话说清
|
||||
- [ ] 骨架列出 3–7 个一级论点
|
||||
- [ ] 关键术语词典 ≥5 条
|
||||
- [ ] 批判阶段列出 ≥3 条作者局限
|
||||
- [ ] 已向用户展示并得到确认
|
||||
|
||||
**用户确认时间**: {{ }}
|
||||
@@ -0,0 +1,73 @@
|
||||
# {{BOOK_TITLE}} — 精华 (DIGEST)
|
||||
|
||||
> 本文由 cangjie-skill 蒸馏生成,只呈现**通过三重验证**的方法论 — 不是全书摘要,是筛过水分的精华。
|
||||
> 想深入某个方法论时,点小节末尾的 skill 链接; 想看全貌,读 [INDEX.md](./INDEX.md)。
|
||||
> 作者: {{AUTHOR}} | {{YEAR}} | 全文约 {{WORD_COUNT}} 字, 预计阅读 {{N}} 分钟
|
||||
|
||||
## 这本书在讲什么
|
||||
|
||||
{{ 2-3 段: 一句话主旨的展开版。作者要解决什么问题、给出了什么答案、这个答案为什么值得听。
|
||||
来自 BOOK_OVERVIEW 的结构部分, 但要写成给读者看的流畅文字, 不是字段填空。}}
|
||||
|
||||
---
|
||||
|
||||
## {{一级论点 1 — 按书的骨架组织章节}}
|
||||
|
||||
{{ 本部分的引入: 这几个方法论共同回答什么问题 }}
|
||||
|
||||
### {{方法论 1 标题}}
|
||||
|
||||
**它解决什么问题**: {{ ... }}
|
||||
|
||||
**核心逻辑**: {{ 3-6 行, 用自己的话, 讲清这个方法论怎么运作、为什么有效 }}
|
||||
|
||||
**书中的用法**: {{ 最有代表性的 1 个案例, 讲清 问题→怎么用→结果 }}
|
||||
|
||||
> {{ 可选: 一句原文金句, ≤150 字 (英文 ≤100 词), 标注出处 }}
|
||||
|
||||
**什么时候会失效**: {{ 1-2 行边界 }}
|
||||
|
||||
→ 深入: [`{{skill-slug}}`](./{{skill-slug}}/SKILL.md)
|
||||
|
||||
### {{方法论 2 标题}}
|
||||
|
||||
{{ 同上结构 }}
|
||||
|
||||
---
|
||||
|
||||
## {{一级论点 2}}
|
||||
|
||||
{{ ... 重复上面的模式, 覆盖所有核心方法论 ... }}
|
||||
|
||||
---
|
||||
|
||||
## 陷阱与反例
|
||||
|
||||
{{ 来自 counter-examples 池: 作者警告的失败模式。
|
||||
每条讲清: 陷阱是什么 → 为什么人会掉进去 (机制) → 预警信号。
|
||||
3-6 条, 挑最有杀伤力的。}}
|
||||
|
||||
---
|
||||
|
||||
## 作者的局限 (读这本书要打的折扣)
|
||||
|
||||
{{ 来自阶段 0 批判部分: 时代局限 / 立场盲点 / 未证明的假设 / 最强反对意见。
|
||||
2-4 条。只报喜不报忧的精华是软文, 不是蒸馏。}}
|
||||
|
||||
---
|
||||
|
||||
## 关键术语速查
|
||||
|
||||
| 术语 | 作者的用法 | 和常识的差异 |
|
||||
|---|---|---|
|
||||
| {{term}} | {{definition}} | {{distinction}} |
|
||||
|
||||
完整词典见 [GLOSSARY.md](./GLOSSARY.md)。
|
||||
|
||||
---
|
||||
|
||||
## 如果只带走三句话
|
||||
|
||||
1. {{ 最核心的一条 }}
|
||||
2. {{ ... }}
|
||||
3. {{ ... }}
|
||||
@@ -0,0 +1,86 @@
|
||||
# {{BOOK_TITLE}} — Skill Index
|
||||
|
||||
> 本书由 cangjie-skill 蒸馏, 共产出 **{{N}}** 个 skills。
|
||||
> 处理时间: {{DATE}}
|
||||
|
||||
## 关于这本书
|
||||
|
||||
- **作者**: {{AUTHOR}}
|
||||
- **出版年**: {{YEAR}}
|
||||
- **一句话主旨**: {{ONE_LINE_THEME}}
|
||||
- **整书理解**: 见 [BOOK_OVERVIEW.md](./BOOK_OVERVIEW.md)
|
||||
- **精华长文** (不读全书看这篇): [DIGEST.md](./DIGEST.md)
|
||||
- **术语词典**: [GLOSSARY.md](./GLOSSARY.md)
|
||||
|
||||
---
|
||||
|
||||
## Skill 列表 (按主题分组)
|
||||
|
||||
### {{主题 1}}
|
||||
|
||||
- [`{{skill-slug-1}}`](./{{skill-slug-1}}/SKILL.md) — {{一句话描述}}
|
||||
- [`{{skill-slug-2}}`](./{{skill-slug-2}}/SKILL.md) — {{一句话描述}}
|
||||
|
||||
### {{主题 2}}
|
||||
|
||||
- [`{{skill-slug-3}}`](./{{skill-slug-3}}/SKILL.md) — {{一句话描述}}
|
||||
|
||||
---
|
||||
|
||||
## 引用图
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[skill-a] -->|depends-on| B[skill-b]
|
||||
A -.->|contrasts-with| C[skill-c]
|
||||
B ===>|composes-with| D[skill-d]
|
||||
```
|
||||
|
||||
图例:
|
||||
- `-->` depends-on
|
||||
- `-.->` contrasts-with
|
||||
- `===>` composes-with
|
||||
|
||||
---
|
||||
|
||||
## 推荐学习顺序
|
||||
|
||||
(从依赖图的叶子节点开始, 向上)
|
||||
|
||||
1. **{{skill-a}}** — 最基础, 没有前置
|
||||
2. **{{skill-b}}** — 依赖 skill-a
|
||||
3. **{{skill-c}}** — 依赖 skill-a, 与 skill-b 互补
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## 安装使用
|
||||
|
||||
本目录是构建产物, 宿主不会从这里加载 skill。要让 agent 真正调用, 把 skill 目录复制到宿主的 skills 目录:
|
||||
|
||||
```bash
|
||||
# 用户级 (所有项目可用)
|
||||
cp -r {{skill-slug-1}} ~/.claude/skills/
|
||||
|
||||
# 或项目级
|
||||
cp -r {{skill-slug-1}} <project>/.claude/skills/ # Claude Code
|
||||
cp -r {{skill-slug-1}} <project>/.cursor/skills/ # Cursor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 接入 darwin-skill
|
||||
|
||||
所有 skill 均带有 `test-prompts.json` (darwin-skill 兼容格式), 可直接接入自动进化:
|
||||
|
||||
```
|
||||
darwin evolve books/{{book-slug}}/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 审计轨迹
|
||||
|
||||
- 候选单元池: [candidates/](./candidates/)
|
||||
- 被淘汰的候选 (含原因): [rejected/](./rejected/)
|
||||
- BOOK_OVERVIEW: [BOOK_OVERVIEW.md](./BOOK_OVERVIEW.md)
|
||||
@@ -0,0 +1,121 @@
|
||||
---
|
||||
name: {{skill-slug}}
|
||||
description: |
|
||||
{{何时调用 + 何时不调用 + 关键 trigger 信号, ≤300 字}}
|
||||
source_book: 《{{BOOK_TITLE}}》 {{AUTHOR}}
|
||||
source_chapter: {{章节}}
|
||||
tags: [{{tag1}}, {{tag2}}]
|
||||
related_skills: [] # 阶段 3 填充
|
||||
---
|
||||
|
||||
<!--
|
||||
填写说明 (生成最终 skill 时删除本注释块):
|
||||
- description: 基于 A2 段浓缩, ≤300 字, 必须含"何时调用 + 何时不调用 + 关键 trigger 信号"。
|
||||
好例: "用户在纠结一个决策、列举正面理由却理不出头绪时;或在问'怎么做 X 才能成功'时。不适用于: 纯信息查询、日常琐碎选择。"
|
||||
关键 trigger 词建议中英双写, 提高英文提问场景的触发准确率。
|
||||
- source_chapter: 书填章节/页码; 视频填时间戳/分 P; 播客填集数。
|
||||
- source_book / tags / related_skills 为审计与链接用的扩展字段, 宿主加载 skill 时只读 name + description。
|
||||
-->
|
||||
|
||||
# {{Skill Title}}
|
||||
|
||||
## R — 原文 (Reading)
|
||||
|
||||
> {{原文引用, ≤150 字 (英文 ≤100 词), 必须标注章节/页码/时间戳}}
|
||||
>
|
||||
> — {{AUTHOR}}, {{CHAPTER}}
|
||||
|
||||
---
|
||||
|
||||
## I — 方法论骨架 (Interpretation)
|
||||
|
||||
{{ 用自己的话重写, 5-15 行。
|
||||
读完这段, 一个没读过原书的人应当能理解这个方法论在做什么。
|
||||
禁止照搬原文, 禁止堆砌修辞。}}
|
||||
|
||||
---
|
||||
|
||||
## A1 — 书中的应用 (Past Application)
|
||||
|
||||
### 案例 1: {{案例名}}
|
||||
- **问题**: {{作者遇到了什么}}
|
||||
- **方法论的使用**: {{作者怎么用这个方法论思考}}
|
||||
- **结论**: {{得出了什么}}
|
||||
- **结果**: {{实际发生了什么}}
|
||||
|
||||
### 案例 2 (如有)
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## A2 — 触发场景 (Future Trigger) ★
|
||||
|
||||
### 用户会在什么情境下需要这个 skill?
|
||||
|
||||
1. {{场景 1 — 具体到可识别的情况}}
|
||||
2. {{场景 2}}
|
||||
3. {{场景 3}}
|
||||
|
||||
### 语言信号 (用户的话里出现这些就应激活)
|
||||
|
||||
- "{{典型措辞 1}}"
|
||||
- "{{典型措辞 2}}"
|
||||
- "{{典型措辞 3}}"
|
||||
|
||||
### 与相邻 skill 的区分
|
||||
|
||||
- 与 `{{related-skill-a}}` 的区别: {{ ... }}
|
||||
- 与 `{{related-skill-b}}` 的区别: {{ ... }}
|
||||
|
||||
---
|
||||
|
||||
## E — 可执行步骤 (Execution)
|
||||
|
||||
当 skill 被激活后, agent 应按以下步骤执行:
|
||||
|
||||
1. **{{步骤 1}}**
|
||||
- 完成标准: {{如何判断这一步已完成}}
|
||||
|
||||
2. **{{步骤 2}}**
|
||||
- 完成标准: {{ ... }}
|
||||
- 判停条件: 若 {{X}} 则跳到步骤 {{N}}
|
||||
|
||||
3. **{{步骤 3}}**
|
||||
- 完成标准: {{ ... }}
|
||||
|
||||
---
|
||||
|
||||
## B — 边界 (Boundary) ★
|
||||
|
||||
### 不要在以下情况使用此 skill
|
||||
|
||||
- {{反场景 1 — 为什么不适用}}
|
||||
- {{反场景 2}}
|
||||
|
||||
### 作者在书中警告的失败模式
|
||||
|
||||
- {{ 来自 counter-example-extractor 的对应反例 }}
|
||||
|
||||
### 作者的盲点 / 时代局限
|
||||
|
||||
- {{ 来自阶段 0 批判阶段 }}
|
||||
|
||||
### 容易混淆的邻近方法论
|
||||
|
||||
- {{ ... }}
|
||||
|
||||
---
|
||||
|
||||
## 相关 skills (阶段 3 填充)
|
||||
|
||||
- depends-on: {{}}
|
||||
- contrasts-with: {{}}
|
||||
- composes-with: {{}}
|
||||
|
||||
---
|
||||
|
||||
## 审计信息
|
||||
|
||||
- **验证通过**: V1 ✓ / V2 ✓ / V3 ✓
|
||||
- **测试通过率**: {{%}} (详见 test-prompts.json)
|
||||
- **蒸馏时间**: {{DATE}}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"skill": "{{skill-slug}}",
|
||||
"version": "0.1.0",
|
||||
"source_book": "{{BOOK_TITLE}} — {{AUTHOR}}",
|
||||
"darwin_compatible": true,
|
||||
"test_cases": [
|
||||
{
|
||||
"id": "should-trigger-01",
|
||||
"type": "should_trigger",
|
||||
"prompt": "{{用户的典型话语 1 — 正面场景}}",
|
||||
"expected_behavior": "应激活 {{skill-slug}}, 并 {{期望的具体动作}}",
|
||||
"notes": "{{为什么这是正面场景}}"
|
||||
},
|
||||
{
|
||||
"id": "should-trigger-02",
|
||||
"type": "should_trigger",
|
||||
"prompt": "{{用户的典型话语 2}}",
|
||||
"expected_behavior": "...",
|
||||
"notes": "..."
|
||||
},
|
||||
{
|
||||
"id": "should-trigger-03",
|
||||
"type": "should_trigger",
|
||||
"prompt": "{{用户的典型话语 3}}",
|
||||
"expected_behavior": "...",
|
||||
"notes": "..."
|
||||
},
|
||||
{
|
||||
"id": "should-not-trigger-01",
|
||||
"type": "should_not_trigger",
|
||||
"prompt": "{{诱饵 1 — 看似相关但实际不该调用}}",
|
||||
"expected_behavior": "不应激活本 skill, 因为 {{理由}}",
|
||||
"notes": "诱饵: {{这是什么类型的诱饵}}"
|
||||
},
|
||||
{
|
||||
"id": "should-not-trigger-02",
|
||||
"type": "should_not_trigger",
|
||||
"prompt": "{{诱饵 2 — 应触发同书另一个 skill 的场景}}",
|
||||
"expected_behavior": "不应激活本 skill, 应激活 {{sibling-skill-slug}}",
|
||||
"notes": "跨 skill 混淆诱饵 (硬性要求至少 1 条): 防止同书 skill 互相抢调用"
|
||||
},
|
||||
{
|
||||
"id": "edge-01",
|
||||
"type": "edge_case",
|
||||
"prompt": "{{边界模糊场景}}",
|
||||
"expected_behavior": "{{期望的合理判断 — 可能是调用, 可能是不调用, 但要说清为什么}}",
|
||||
"notes": "边界: {{为什么这是边界}}"
|
||||
}
|
||||
],
|
||||
"minimum_pass_rate": 0.8,
|
||||
"notes": "至少 3 条 should_trigger + 2 条 should_not_trigger + 1 条 edge_case。全部 should_not_trigger 必须通过 (诱饵容错为 0), 且其中至少 1 条是同书兄弟 skill 的场景 (跨 skill 混淆测试)。"
|
||||
}
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
---
|
||||
name: codebase-migrate
|
||||
description: Run large codebase migrations and multi-file refactors. Uses the Composio CLI to coordinate issue tracking, batched PRs, and CI verification while the agent executes the transforms locally across hundreds of files.
|
||||
metadata:
|
||||
short-description: Codebase migrations + multi-file refactors
|
||||
---
|
||||
|
||||
# Codebase Migrate
|
||||
|
||||
Coordinate framework upgrades, API renames, config rewrites, and structural refactors across hundreds of files. Local edits are driven by the agent; the [Composio CLI](https://docs.composio.dev/docs/cli) handles the surrounding ceremony: tracking issues, per-batch PRs, and CI verification.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Framework upgrade (React 17 → 19, Node 18 → 22, Django 4 → 5).
|
||||
- API rename across a monorepo (e.g., `getUserById` → `users.byId`).
|
||||
- Config/format migration (webpack → vite, eslint → biome, jest → vitest).
|
||||
- Any "change 200 files the same way" task that needs to ship in reviewable slices.
|
||||
|
||||
## Prereqs
|
||||
|
||||
```bash
|
||||
curl -fsSL https://composio.dev/install | bash
|
||||
composio login
|
||||
composio link github # for PRs + CI status
|
||||
composio link linear # or jira — for migration tracking
|
||||
```
|
||||
|
||||
Local tools the agent will use directly: `git`, `rg`, `jscodeshift`/`ts-morph`/`comby`/`ast-grep` (language-appropriate), and your test runner.
|
||||
|
||||
## Planning Phase
|
||||
|
||||
1. **Define the transform precisely.** Bad: "migrate to vitest." Good: "replace `jest.mock` with `vi.mock`, swap `jest.fn()` for `vi.fn()`, rename `jest.config.js` → `vitest.config.ts` using template X."
|
||||
2. **Scope the blast radius:**
|
||||
```bash
|
||||
rg -l 'jest\.(mock|fn|spyOn)' | wc -l
|
||||
rg -l 'from "jest"' | sort
|
||||
```
|
||||
3. **File a tracking issue:**
|
||||
```bash
|
||||
composio execute LINEAR_CREATE_ISSUE -d '{
|
||||
"teamId":"TEAM_ID",
|
||||
"title":"Migrate test runner: jest → vitest",
|
||||
"description":"Batches of ~25 files. Checkpoint after each PR lands green."
|
||||
}'
|
||||
```
|
||||
|
||||
## Execute in Reviewable Batches
|
||||
|
||||
Loop: pick N files → transform → test → PR → wait for green → merge → next batch.
|
||||
|
||||
```bash
|
||||
# Batch helper: first 25 untouched files matching the pattern
|
||||
BATCH=$(rg -l 'jest\.mock' | grep -v done.list | head -25)
|
||||
echo "$BATCH" > batch.list
|
||||
```
|
||||
|
||||
The agent runs the codemod on `batch.list`, then:
|
||||
|
||||
```bash
|
||||
git checkout -b migrate/vitest-batch-03
|
||||
xargs < batch.list codemod-runner # e.g. jscodeshift / ts-morph / comby
|
||||
npm test -- --changed
|
||||
git add -A && git commit -m "migrate(test): jest → vitest (batch 3)"
|
||||
git push -u origin migrate/vitest-batch-03
|
||||
|
||||
composio execute GITHUB_CREATE_A_PULL_REQUEST -d '{
|
||||
"owner":"acme","repo":"app",
|
||||
"head":"migrate/vitest-batch-03","base":"main",
|
||||
"title":"migrate(test): jest → vitest (batch 3)",
|
||||
"body":"Part of LIN-482. 25 files. Codemod: `transforms/jest-to-vitest.ts`."
|
||||
}'
|
||||
```
|
||||
|
||||
Then poll CI and merge when green:
|
||||
|
||||
```bash
|
||||
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
|
||||
-d '{"owner":"acme","repo":"app","branch":"migrate/vitest-batch-03"}'
|
||||
```
|
||||
|
||||
## Workflow Script
|
||||
|
||||
`scripts/migrate-batch.ts`, run per batch via `composio run --file scripts/migrate-batch.ts -- --batch 3`:
|
||||
|
||||
```ts
|
||||
const batch = process.argv[process.argv.indexOf("--batch") + 1];
|
||||
|
||||
const pr = await execute("GITHUB_CREATE_A_PULL_REQUEST", {
|
||||
owner: "acme", repo: "app",
|
||||
head: `migrate/vitest-batch-${batch}`, base: "main",
|
||||
title: `migrate(test): jest → vitest (batch ${batch})`,
|
||||
body: `Part of LIN-482. See transforms/jest-to-vitest.ts.`
|
||||
});
|
||||
|
||||
await execute("LINEAR_CREATE_COMMENT", {
|
||||
issueId: "LIN-482",
|
||||
body: `Opened PR #${pr.number}: ${pr.html_url}`
|
||||
});
|
||||
```
|
||||
|
||||
## Safety Rails
|
||||
|
||||
- **One transform per PR.** Never mix a rename with a format change.
|
||||
- **Keep a `done.list`** of files already migrated so the next batch skips them.
|
||||
- **Run the full test suite on the last batch**, even if per-batch PRs ran `--changed`.
|
||||
- **Codemod first, hand-edit second.** If the codemod misses 3 files, patch them manually and note it in the PR body.
|
||||
- **Roll back per-batch**, not globally. Each PR should revert cleanly.
|
||||
|
||||
## Verification Loop
|
||||
|
||||
After each merge:
|
||||
|
||||
```bash
|
||||
rg 'jest\.(mock|fn|spyOn)' | wc -l # should trend to 0
|
||||
npm test # full suite
|
||||
composio execute GITHUB_LIST_WORKFLOW_RUNS_FOR_A_REPOSITORY \
|
||||
-d '{"owner":"acme","repo":"app","branch":"main","event":"push"}' \
|
||||
| jq '.workflow_runs[0].conclusion'
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Codemod regex catches too much** → switch to AST-based tooling (`ast-grep`, `ts-morph`) for structural matches.
|
||||
- **Tests pass locally, CI fails** → pin Node/Python version parity; check `.nvmrc` / `pyproject.toml`.
|
||||
- **PR too big to review** → cut batch size in half; maintainers won't review 800-line diffs.
|
||||
- **Conflicts between batches** → rebase the open batch before merging the current one; never force-push merged batches.
|
||||
|
||||
Full CLI reference: [docs.composio.dev/docs/cli](https://docs.composio.dev/docs/cli)
|
||||
+1
-2
@@ -249,7 +249,7 @@ NEVER:
|
||||
<references>
|
||||
|
||||
Core methodology:
|
||||
- [confidence.md](../pathfinding/references/confidence.md) — confidence calibration (shared with pathfinding)
|
||||
- [confidence-calibration.md](references/confidence-calibration.md) — evidence-based confidence calibration
|
||||
|
||||
Micro-skills (load as needed):
|
||||
- `outfitter:patterns` — extracting and validating patterns
|
||||
@@ -260,7 +260,6 @@ Local references:
|
||||
- [architecture-analysis.md](references/architecture-analysis.md) — system structure mapping
|
||||
|
||||
Related skills:
|
||||
- `outfitter:pathfinding` — clarifying requirements before analysis
|
||||
- `outfitter:debugging` — structured bug investigation
|
||||
|
||||
</references>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Confidence Calibration
|
||||
|
||||
Confidence measures how strongly the available evidence supports a codebase
|
||||
finding. It does not measure requirement clarity or implementation readiness.
|
||||
|
||||
## Calibration Dimensions
|
||||
|
||||
Consider these dimensions together; do not average them mechanically:
|
||||
|
||||
- **Directness**: runtime observation and source code outweigh inference.
|
||||
- **Coverage**: evidence spans the relevant execution paths and modules.
|
||||
- **Corroboration**: code, tests, documentation, and history agree.
|
||||
- **Counter-evidence**: plausible alternatives and contradictory cases were checked.
|
||||
- **Remaining gaps**: unknown behavior is bounded and stated explicitly.
|
||||
|
||||
## Typical Levels
|
||||
|
||||
| Level | Evidence state |
|
||||
| --- | --- |
|
||||
| 0 | No repository evidence collected yet. |
|
||||
| 1 | Broad structure or search results only. |
|
||||
| 2 | Relevant code located, but behavior or scope is not verified. |
|
||||
| 3 | Main path traced with some corroboration; meaningful gaps remain. |
|
||||
| 4 | Multiple sources support the finding and counter-examples were checked. |
|
||||
| 5 | Relevant scope is covered, alternatives are ruled out, and conclusions are directly supported. |
|
||||
|
||||
A clear user request can narrow the investigation but cannot raise confidence in
|
||||
a finding by itself. Documentation alone normally remains at level 1-2. A
|
||||
single code path without tests, history, or runtime confirmation normally
|
||||
remains at level 2-3.
|
||||
|
||||
## Examples
|
||||
|
||||
### Focused Question, Strong Evidence
|
||||
|
||||
Question: "Does deleting this adapter break the HTTP client?"
|
||||
|
||||
Evidence: imports show no production consumer, tests cover the replacement
|
||||
adapter, and history confirms the old adapter was retained only for migration.
|
||||
After checking dynamic loading and configuration references, report at level
|
||||
4-5. Cite each source and distinguish observed facts from the final inference.
|
||||
|
||||
### Cross-Module Finding, Incomplete Evidence
|
||||
|
||||
Question: "Why do all write operations depend on the legacy package?"
|
||||
|
||||
Evidence: searches show imports in several modules, but runtime registration
|
||||
and generated code have not been inspected. Stay at level 2-3. Continue tracing
|
||||
composition roots and tests before claiming an architectural dependency.
|
||||
|
||||
### Early Delivery
|
||||
|
||||
The user asks for findings before runtime behavior or history can be checked.
|
||||
Deliver the verified portion at its current level and include `△ Caveats` with:
|
||||
|
||||
- the evidence already inspected;
|
||||
- assumptions required by the conclusion;
|
||||
- unverified modules or execution paths;
|
||||
- the next checks that would materially change confidence.
|
||||
|
||||
Do not present the early report as level 5 even when the likely explanation is
|
||||
simple.
|
||||
|
||||
## Delivery Check
|
||||
|
||||
Before assigning level 4 or 5, confirm that:
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 alchaincyf (花叔)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+508
@@ -0,0 +1,508 @@
|
||||
---
|
||||
name: darwin-skill
|
||||
description: "Darwin Skill 2.0 (达尔文.skill 2.0): autonomous skill optimizer, v2.0 integrates Microsoft Research SkillLens (arXiv 2605.23899) 9-dim rubric + SkillOpt (arXiv 2605.23904) validation-gated design + human-in-the-loop checkpoints. Evaluates SKILL.md files using a 9-dimension rubric (structure + effectiveness + meta-skill blacklists), runs hill-climbing with git version control, spawns independent judge agents for blind evaluation, validates improvements through test prompts with auto-break on diminishing returns, and generates visual result cards. Use when user mentions \"优化skill\", \"skill评分\", \"自动优化\", \"auto optimize\", \"skill质量检查\", \"达尔文\", \"darwin\", \"帮我改改skill\", \"skill怎么样\", \"提升skill质量\", \"skill review\", \"skill打分\"."
|
||||
---
|
||||
|
||||
# Darwin Skill 2.0
|
||||
|
||||
> **v2.1 · 2026-06-10** — keep/revert 棘轮从「绝对分数 delta」改为「**paired 同-judge 比较 + 奇数 N 多数决**」(绝对分数 ±8 judge 噪音淹没保守编辑的真实增益、是 false-revert 源;within-judge 比较消除换尺污染)。绝对分数降级为 triage-only。
|
||||
> **v2.0 · 2026-05-28** — 吸收 Microsoft Research SkillLens(arXiv 2605.23899)的 9 维评分药方 + SkillOpt(arXiv 2605.23904)的 validation-gated 验证机制 + human in the loop 三层守关。
|
||||
>
|
||||
> 借鉴 Karpathy autoresearch 的自主实验循环,对 skills 进行持续优化。
|
||||
> 核心理念:**评估 → 改进 → 实测验证 → 人类确认 → 保留或回滚 → 生成成果卡片**
|
||||
> GitHub: https://github.com/alchaincyf/darwin-skill
|
||||
|
||||
---
|
||||
|
||||
## 设计哲学
|
||||
|
||||
autoresearch 的精髓:
|
||||
1. **单一可编辑资产** — 每次只改一个 SKILL.md
|
||||
2. **双重评估** — 结构评分(静态分析)+ 效果验证(跑测试看输出)
|
||||
3. **棘轮机制** — 只保留改进,自动回滚退步
|
||||
4. **独立评分** — 评分用子agent,避免「自己改自己评」的偏差
|
||||
5. **人在回路** — 每个skill优化完后暂停,用户确认再继续
|
||||
|
||||
与纯结构审查的区别:不只看 SKILL.md 写得规不规范,更看改完后**实际跑出来的效果是否更好**。
|
||||
|
||||
---
|
||||
|
||||
## 评估 Rubric(9维度,总分100)
|
||||
|
||||
> **设计依据**:基于 SkillLens 论文(arXiv 2605.23899)实证发现——LLM-as-judge 评估 skill 质量准确率仅 46.4%(接近随机),加入 meta-skill 三维度后提升到 73.8%。本 rubric 强化 dim3 / dim5 评分标准,新增 dim9「反例与黑名单」,权重平衡到 100。**目的:让评分对真实质量更敏感,减少 LLM judge 的乐观偏差。**
|
||||
|
||||
### 结构维度(59分)— 静态分析
|
||||
|
||||
| # | 维度 | 权重 | 评分标准 |
|
||||
|---|------|------|---------|
|
||||
| 1 | **Frontmatter质量** | 7 | name规范、description包含做什么+何时用+触发词、≤1024字符、**禁结尾加"灵活应用/根据情况判断"等空话尾巴** |
|
||||
| 2 | **工作流清晰度** | 12 | 步骤明确可执行、有序号、每步有明确输入/输出 |
|
||||
| 3 | **失败模式编码** | 12 | **必须显式编码失败模式**(写出"如果 X 失败 → Y"的明确分支);有fallback路径、错误恢复;**只写正向流程而不写失败分支扣 ≥3 分**(SkillLens meta-skill 维度) |
|
||||
| 4 | **检查点设计** | 6 | 关键决策前有用户确认、防止自主失控;**检查点必须显性标记(🔴/STOP/CHECKPOINT),仅靠"如果...建议..."措辞不算** |
|
||||
| 5 | **可执行具体性** | 18 | 不模糊、有具体参数/格式/示例、可直接执行;**禁止"建议/可以考虑/根据情况/灵活把握/视情况而定"等软化措辞**——出现 ≥3 处扣 ≥3 分(SkillLens actionable specificity 维度) |
|
||||
| 6 | **资源整合度** | 4 | references/scripts/assets引用正确、路径可达 |
|
||||
|
||||
### 效果维度(35分)— 需要实测
|
||||
|
||||
| # | 维度 | 权重 | 评分标准 |
|
||||
|---|------|------|---------|
|
||||
| 7 | **整体架构** | 12 | 结构层次清晰、不冗余不遗漏、与花叔生态一致;**冗余/AI腔废话段落(说白了/换句话说/首先其次综上等花叔禁用词)出现一处扣 1 分** |
|
||||
| 8 | **实测表现** | 23 | 用测试prompt跑一遍,输出质量是否符合skill宣称的能力 |
|
||||
|
||||
### Meta-skill 维度(6分)— 反例与黑名单
|
||||
|
||||
| # | 维度 | 权重 | 评分标准 |
|
||||
|---|------|------|---------|
|
||||
| 9 | **反例与黑名单** | 6 | **skill 必须有"不要做什么"的反例清单**;只写"应该做 X"没有"不要做 Y"扣 ≥3 分;红灯/危险动作/反模式应单独章节列出(SkillLens risk-action blacklist 维度) |
|
||||
|
||||
### 评分规则
|
||||
- 维度1-7、9:每个维度打 1-10 分,乘以权重得到该维度得分
|
||||
- 维度8(实测表现):跑2-3个测试prompt,按输出质量打1-10分
|
||||
- **总分 = Σ(维度分 × 权重) / 10**,满分100
|
||||
- ⚠️ **绝对总分只用于 triage(粗排「哪支最弱、先改谁」),绝不用于 keep/revert**。实测:同一份**未改**文字换个 judge 评,总分可摆 **±8**(一支只加了 3 个 🔴 字元的 skill、单评却 −8.5,全是 judge 换尺、非真实退步)。keep/revert 一律走 **Phase 2 的 paired 比较**。
|
||||
- **为什么**:LLM judge 给的是**抽样、不是测量**——分数住在「文字 × 该 judge 当下选的标准」里,不是文字属性。绝对总分 = 用**两台未校准磅秤**量节食前后,差值大半是磅秤差;paired = **同一台磅秤**量前后,误差相减抵销。pairwise preference >> absolute scoring 是 LLM judge 的已知结论(RLHF 用 pairwise 不用绝对分同因)。
|
||||
|
||||
### Rubric 的实证基础
|
||||
|
||||
rubric 设计依据来自 **SkillLens 论文(arXiv 2605.23899)** + **本机 controlled study**:
|
||||
|
||||
- SkillLens 发现 LLM-as-judge 准确率仅 46.4%(接近随机),加入 meta-skill 三维度后升到 73.8%
|
||||
- 本机对 huashu-research 做 4 类 degradation → 5 个独立 judge 盲测一致 V1>V2,Δ 均值 +46.5(5/5 high confidence)
|
||||
|
||||
**结论**:rubric 能识别 gross degradation,但 fine-grained quality difference 仍不可信,**重要决策必须人审**。
|
||||
|
||||
→ 详细论文证据 + 5 judges 完整数据 + HL 实战案例数字见 [references/skilllens-evidence.md](references/skilllens-evidence.md)
|
||||
|
||||
### 关于「实测表现」维度
|
||||
|
||||
这是与纯结构评分最大的区别。评分方式:
|
||||
|
||||
1. 为每个skill设计2-3个**典型用户prompt**(不是边缘case,是最常见的使用场景)
|
||||
2. 用子agent执行:一个带skill跑,一个不带skill跑(baseline)
|
||||
3. 对比输出质量,从以下角度打分:
|
||||
- 输出是否完成了用户意图?
|
||||
- 相比不带skill的baseline,质量提升明显吗?
|
||||
- 有没有skill引入的负面影响(过度冗余、跑偏、格式奇怪)?
|
||||
|
||||
若子 agent 不可用(超时/资源限制),退化为「干跑验证」:读完 skill 后模拟一个典型 prompt 的执行思路,判断流程是否合理;必须在 results.tsv 标注 `dry_run`。**dry_run 比例 > 30% → 评估失效警告**(来自本机 controlled study:dim8 实测维度权重 23%,无 full_test 验证时分数不可信)。
|
||||
|
||||
---
|
||||
|
||||
## Runtime 适配性审查(gate 项,独立于 9 维度评分)
|
||||
|
||||
skill 应当能在 Claude Code / Codex / Cursor / OpenClaw / Hermes / Gemini CLI / OpenCode 等 50+ skills-compatible runtime 通用——否则其他 agent 解析时会被「在 Claude Code 里」「Claude Code skill」等措辞误判为「不是给我用的」直接拒装(实例:nuwa-skill 因此被 Marvis agent 拒绝)。
|
||||
|
||||
### Phase 1 基线评估时强制跑一次红灯扫描
|
||||
|
||||
```bash
|
||||
grep -nE "(在 Claude Code|Claude Code skill|Claude Code 用户|Cursor only|Codex 中|^\[!\[Claude Code|~/\.claude/skills/[a-z]|/plugin install\b)" SKILL.md README.md 2>/dev/null
|
||||
```
|
||||
|
||||
输出非空 = 红灯命中 → 强制把 Phase 2 第一轮定为 P0「runtime drift 修复」(写入 results.tsv 的 note 列 `runtime_warn=N`)。
|
||||
|
||||
### 例外(允许的「Claude Code 痕迹」)
|
||||
|
||||
frontmatter 触发词、花叔生态内部 skill 名引用、明确标注 runtime-specific 章节、commit message——这些正当出现,不算红灯。
|
||||
|
||||
→ 红灯/绿灯完整对照表 + 例外清单详细规则 + Phase 1/2/3 各阶段审查时机见 [references/runtime-neutrality.md](references/runtime-neutrality.md)
|
||||
|
||||
---
|
||||
|
||||
## 自主优化循环
|
||||
|
||||
### Phase 0: 初始化
|
||||
|
||||
```
|
||||
1. 确认优化范围:
|
||||
- 全部skills → 扫描 .claude/skills/*/SKILL.md
|
||||
- 指定skills → 用户指定列表
|
||||
2. 创建 git 分支:auto-optimize/YYYYMMDD-HHMM
|
||||
3. 初始化 results.tsv(如不存在)
|
||||
4. 读取现有 results.tsv 了解历史优化记录
|
||||
```
|
||||
|
||||
### Phase 0.5: 测试Prompt设计
|
||||
|
||||
在评估之前,为每个skill设计测试prompt。这步很关键——没有测试prompt,「实测表现」维度就打不了分。
|
||||
|
||||
```
|
||||
for each skill:
|
||||
1. 读取 SKILL.md,理解它做什么
|
||||
2. 设计2-3个测试prompt,覆盖:
|
||||
- 最典型的使用场景(happy path)
|
||||
- 一个稍复杂或有歧义的场景
|
||||
3. 保存到 skill目录/test-prompts.json:
|
||||
[
|
||||
{"id": 1, "prompt": "用户会说的话", "expected": "期望输出的简短描述"},
|
||||
{"id": 2, "prompt": "...", "expected": "..."}
|
||||
]
|
||||
```
|
||||
|
||||
展示所有测试prompt给用户,**确认后再进入评估**。测试prompt的质量决定了优化方向是否正确。
|
||||
|
||||
### Phase 1: 基线评估(Baseline)— triage 用途
|
||||
|
||||
> **本阶段绝对分数是 triage 排名(决定先改谁),不是 keep/revert 基准**。judge 对 gross 差异会一致(「哪支最弱」可信),对 fine-grained delta 不可信(±8 噪音)。keep/revert 在 Phase 2 用 paired 比较。
|
||||
|
||||
```
|
||||
for each skill in 优化范围:
|
||||
|
||||
# 结构评分(主agent可以做)
|
||||
1. 读取 SKILL.md 全文
|
||||
2. 按维度1-7逐项打分(附简短理由)
|
||||
|
||||
# 效果评分(用子agent做,独立于主agent)
|
||||
3. 对每个测试prompt,spawn子agent:
|
||||
- with_skill: 带着SKILL.md执行测试prompt
|
||||
- baseline: 不带skill执行同一prompt
|
||||
4. 对比两组输出,打维度8的分
|
||||
|
||||
# 汇总
|
||||
5. 计算加权总分
|
||||
6. 记录到 results.tsv
|
||||
```
|
||||
|
||||
**如果子agent不可用**(超时、环境限制),维度8用干跑验证打分,标注 `dry_run`。不要因为跑不了测试就跳过这个维度——哪怕是模拟推演也比完全不看效果好。
|
||||
|
||||
基线评估完成后,展示评分卡:
|
||||
|
||||
```
|
||||
┌──────────────────────────┬───────┬──────────────┬──────────────┐
|
||||
│ Skill │ Score │ 结构短板 │ 效果短板 │
|
||||
├──────────────────────────┼───────┼──────────────┼──────────────┤
|
||||
│ huashu-proofreading │ 78 │ 边界条件 │ 测试prompt2 │
|
||||
│ huashu-slides │ 72 │ 指令具体性 │ baseline持平 │
|
||||
├──────────────────────────┼───────┼──────────────┼──────────────┤
|
||||
│ 平均 │ 75 │ │ │
|
||||
└──────────────────────────┴───────┴──────────────┴──────────────┘
|
||||
```
|
||||
|
||||
**🔴 CHECKPOINT · 🛑 STOP:暂停等用户确认,再进入优化循环。**
|
||||
|
||||
### Phase 2: 优化循环
|
||||
|
||||
用户确认后,按基线分数从低到高排序,先优化最弱的。
|
||||
|
||||
```
|
||||
for each skill:
|
||||
round = 0
|
||||
while round < MAX_ROUNDS (默认3):
|
||||
round += 1
|
||||
|
||||
# Step 1: 诊断
|
||||
找出加权短板最大的维度:weighted_gap = weight × (10 - score) / 10,结构或效果都算
|
||||
# /10 与「总分 = Σ(维度分 × 权重) / 10」同标度:weighted_gap 就是该维度还能贡献的总分数
|
||||
# 为什么不用「原始分最低」:低权重维度会制造进步幻觉——issue #18 实战中
|
||||
# dim9(权重6,gap 5.3)原始分最低被优先修,而 dim8(权重23)加权短板最大(11.5)却 4 轮未动
|
||||
# 加权短板相近(差距 ≤ 1.0,同上述标度)时,回退为原始分升序
|
||||
# HL-3 警告:dim2/dim3/dim4 是相关簇,修一个时另两个常跟着涨
|
||||
# → 不要因为 dim3 短板最大就单独修,要看整簇短板再决定是否同步改
|
||||
|
||||
# Step 2: 提出改进方案
|
||||
针对该维度,生成1个具体改进方案:
|
||||
- 改什么(具体段落/行)
|
||||
- 为什么改(对应rubric哪条)
|
||||
- 预期提升多少分
|
||||
|
||||
# Step 3: 执行改进
|
||||
编辑 SKILL.md
|
||||
git add + commit(message: "optimize {skill}: {改进摘要}")
|
||||
|
||||
# Step 4: Paired 重新评估(取代绝对重打分——绝对分数 judge 噪音 ±8、淹没保守编辑的 +3~8 真实增益)
|
||||
spawn N=3 独立 judge,每个【同一次 call 内】读两版:
|
||||
- 改前版:git show HEAD:<skill-path>/SKILL.md(上一个 kept commit)
|
||||
- 改后版:working tree 当前 SKILL.md
|
||||
照 9 维 rubric 当【比较准则】(不是各打绝对分),回 {better | worse | tie} + margin{clear|slight} + 一句理由。
|
||||
关键:同一 judge 在一次 call 内比两版 → 它那把不准的尺对两版【等量作用、在比较时抵销】(within-judge cancellation),
|
||||
这正是 paired 优于绝对的机制。N 取奇数(默认 3;close call 升 5)。
|
||||
|
||||
# Step 5: 共识决策(多数决,取代「新总分 > 旧总分」)
|
||||
cur = 投 better 的 judge 数;wor = 投 worse 的;
|
||||
if cur >= wor: # 多数说改后 ≥ 改前(含 tie)
|
||||
status = "keep"
|
||||
# HL-4 见好就收:连续 2 轮多数 judge 判 margin=slight 或 tie → break 进 Phase 3
|
||||
else: # 多数说 worse —— 这才是真退步(已扣掉换尺噪音)
|
||||
status = "revert"
|
||||
git revert HEAD(创建新commit回滚,不用 reset --hard)
|
||||
记录到 results.tsv(note 记 vote 比数 + 一句 worse 理由)
|
||||
break
|
||||
# 单评绝对分数出现「负 delta」≠ revert 信号;必须经 paired 多数判 worse 才 revert(否则在丢真实增益)
|
||||
|
||||
# Step 6: 日志
|
||||
results.tsv 追加行
|
||||
|
||||
# === 🔴 CHECKPOINT · 每个 skill 优化完后强制人审 ===
|
||||
展示该skill的改动摘要:
|
||||
- git diff(改前 vs 改后)
|
||||
- 分数变化(哪些维度提升/下降)
|
||||
- 测试prompt输出对比(如果跑过的话)
|
||||
等用户确认 OK 再继续下一个skill。
|
||||
如果用户说"不好",回滚到该skill的优化前版本。
|
||||
```
|
||||
|
||||
### Phase 2.5: 探索性重写(按需触发)
|
||||
|
||||
当 hill-climbing 连续2个skill都在 round 1 就 break(涨不动)时,提议一次「探索性重写」:
|
||||
|
||||
```
|
||||
1. 选一个瓶颈skill
|
||||
2. git stash 保存当前最优版本
|
||||
3. 从头重写SKILL.md(不是微调,是重新组织结构和表达方式)
|
||||
4. 重新评估
|
||||
5. if 重写版 > stash版: 采用重写版
|
||||
else: git stash pop 恢复
|
||||
```
|
||||
|
||||
这解决了 hill-climbing 的局部最优问题——有时候需要「先拆后建」才能突破瓶颈。
|
||||
**🔴 CHECKPOINT · 🛑 STOP:必须征得用户同意后才执行。**
|
||||
|
||||
### Phase 3: 汇总报告
|
||||
|
||||
```
|
||||
## 优化报告
|
||||
|
||||
### 总览
|
||||
- 优化skills数:N
|
||||
- 总实验次数:M
|
||||
- 保留改进:X(Y%)
|
||||
- 回滚次数:Z
|
||||
- 实测验证:A次完整测试 / B次干跑
|
||||
|
||||
### 分数变化
|
||||
┌──────────────────────────┬────────┬────────┬────────┐
|
||||
│ Skill │ Before │ After │ Δ │
|
||||
├──────────────────────────┼────────┼────────┼────────┤
|
||||
│ huashu-proofreading │ 78 │ 87 │ +9 │
|
||||
│ huashu-slides │ 72 │ 83 │ +11 │
|
||||
├──────────────────────────┼────────┼────────┼────────┤
|
||||
│ 平均 │ 75 │ 85 │ +10 │
|
||||
└──────────────────────────┴────────┴────────┴────────┘
|
||||
|
||||
### 主要改进
|
||||
1. [skill-A] 补充了边界条件处理,测试输出质量提升明显
|
||||
2. [skill-B] 重组了workflow结构,baseline对比优势增大
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## results.tsv 格式
|
||||
|
||||
```tsv
|
||||
timestamp commit skill old_score new_score status dimension note eval_mode
|
||||
2026-03-31T10:00 baseline huashu-proofreading - 78 baseline - 初始评估 full_test
|
||||
2026-03-31T10:05 a1b2c3d huashu-proofreading 78 84 keep 边界条件 补充fallback full_test
|
||||
2026-03-31T10:10 b2c3d4e huashu-proofreading 84 82 revert 指令具体性 过度细化 dry_run
|
||||
```
|
||||
|
||||
`eval_mode` 列:`paired`(同 judge 比改前/改后,**keep/revert 权威依据**)|`full_test`(子agent 跑 prompt)|`dry_run`(模拟推演、仅供参考)。
|
||||
paired 行:`new_score` 栏记 vote 比数(如 `3-0 better`),`note` 记一句裁断理由。例:
|
||||
```tsv
|
||||
2026-06-10T06:30 paired some-skill (绝对 87.3→78.8 = judge 噪音) 3-0 better paired 推翻单评假退步 paired
|
||||
```
|
||||
文件位置:`.claude/skills/darwin-skill/results.tsv`
|
||||
|
||||
---
|
||||
|
||||
## 实战 high-leverage 操作(精髓速查)
|
||||
|
||||
4 条经实战验证(huashu-gpt-image +10.85 / huashu-weread-advisor +14.9 / claude-design +16.5)。详细案例数据见 [references/skilllens-evidence.md](references/skilllens-evidence.md) 的「HL 实战案例」节。
|
||||
|
||||
- **HL-1(dim4)显性视觉标记是杠杆**:加 🔴 CHECKPOINT / 🛑 STOP,靠「必须」措辞不行——LLM 解析时扫描视觉标记。4 行改动撬动 dim4 +3 分
|
||||
- **HL-2(dim3)if-then 三段式 fallback 表**:把「症状/解法」两列升级为「触发条件 / 一线修复 / 仍失败兜底」三段式。SkillLens failure-mechanism encoding 维度的落地
|
||||
- **HL-3(Phase 2 诊断)维度相关簇警告**:dim2/3/4 是相关簇——修 dim3 时 dim2 常跟着涨。「找最大加权短板维度」时同时看相关簇短板再决定是否同步改
|
||||
- **HL-4(Phase 2 退出)触顶自动 break**:连续 2 轮 Δ < 2 分 → break 进 Phase 3。+0.15 是停手信号不是继续信号;硬凑 MAX_ROUNDS=3 引入 over-engineering
|
||||
|
||||
---
|
||||
|
||||
## 优化策略库
|
||||
|
||||
按优先级排序,每轮只做最高优先级的一个:
|
||||
|
||||
### P0: Runtime 适配性问题(gate 项命中 → 必须先修)
|
||||
- README/SKILL.md 出现红灯措辞(如「在 Claude Code 里」「Claude Code skill」)→ 替换为 runtime-neutral 措辞
|
||||
- Badge 钉死单一 runtime → 改为 `Agent Skills Standard` + `skills.sh` + `Multi-Runtime` 三个中立 badge
|
||||
- 安装章节只给一种 runtime 的路径 → 改为「一行命令(auto-detect)+ 手动路径表 + 作为参考资料」三层结构
|
||||
- 工作流硬编码 runtime-specific 工具且无 fallback → 给出通用替代方案或标注「仅在某 runtime 可用」
|
||||
- 例外:skill 名明确标注单 runtime(如 `xxx-codex`)的,可跳过本项
|
||||
|
||||
### P0: 效果问题(实测发现的)
|
||||
- 测试输出偏离用户意图 → 检查skill是否有误导性指令
|
||||
- 带skill比不带还差 → skill可能过度约束,考虑精简
|
||||
- 输出格式不符合预期 → 补充明确的输出模板
|
||||
|
||||
### P1: 结构性问题
|
||||
- Frontmatter缺少触发词 → 补充中英文触发词
|
||||
- 缺少Phase/Step结构 → 重组为线性流程
|
||||
- 缺少用户确认检查点 → 在关键决策处插入
|
||||
|
||||
### P2: 具体性问题
|
||||
- 步骤模糊("处理图片")→ 改为具体操作和参数
|
||||
- 缺少输入/输出规格 → 补充格式、路径、示例
|
||||
- 缺少异常处理 → 补充 "如果X失败,则Y"
|
||||
|
||||
### P3: 可读性问题
|
||||
- 段落过长 → 拆分+用表格
|
||||
- 重复描述 → 合并去重
|
||||
- 缺少速查 → 添加TL;DR或决策树
|
||||
|
||||
---
|
||||
|
||||
## 异常与边界条件
|
||||
|
||||
流程假设环境理想,但实操常遇异常。以下预定义 fallback,保证优化过程不会「一跑就卡住」。
|
||||
|
||||
| 场景 | 触发条件 | 处理动作 |
|
||||
|---|---|---|
|
||||
| 不在 git 仓库 | `git rev-parse` 失败 | 询问用户:执行 `git init` 或回退到文件备份;用户选后者则 `cp SKILL.md SKILL.md.bak.YYYYMMDD-HHMM` 代替 revert |
|
||||
| results.tsv 缺失 | 文件不存在 | 新建并写表头行(9列:含 eval_mode) |
|
||||
| results.tsv 损坏 | 列数不匹配 / 非TSV | 备份为 `.bak.YYYYMMDD-HHMM` 后重建,告知用户 |
|
||||
| 分支已存在 | `git checkout -b` 失败 | 分支名末尾加 `-2` / `-3`;第3次失败则切回现有分支并询问继续还是新起 |
|
||||
| `git revert` 失败 | 冲突 / 工作树脏 | 先 `git stash`,重试;仍失败则从上一个 commit 的 SKILL.md 读出覆盖当前文件手动恢复 |
|
||||
| MAX_ROUNDS 触顶(默认3) | 已跑3轮仍有短板 | 不强制 break,展示当前最弱维度问用户「继续加1轮 / 进入Phase 2.5 / 收工」 |
|
||||
| 优化后超 150% 体积 | 新文件 > 原 × 1.5 | 拒绝提交,回到改进步骤精简(删冗余/合并重复),再评 |
|
||||
| test-prompts.json 已存在 | 文件已在 skill 目录 | 默认复用并展示,问用户「复用 / 重写 / 追加」三选一 |
|
||||
| SKILL.md 找不到 | 目录存在但无 SKILL.md | 该 skill 终止,results.tsv 记 `status=error`,继续下一个 |
|
||||
| 分数计算规则 | 浮点精度漂移 | 总分保留 1 位小数,改进需严格 > 旧分(不靠四舍五入) |
|
||||
|
||||
**原则**:异常先告知用户,再按规则处理;绝不静默跳过或静默失败。
|
||||
|
||||
---
|
||||
|
||||
## darwin 操作反例黑名单(dim9 应用:darwin 自己优化时不要做的事)
|
||||
|
||||
来自本机 results.tsv 早期 40 次 0 revert 的教训 + Judge G/H 自指评估暴露的反模式。每条都是**真实踩过的坑**。
|
||||
|
||||
| # | 反模式 | 为什么不要做 | 替代做法 |
|
||||
|---|---|---|---|
|
||||
| 1 | **同 context 自评自改** | 改完后立刻在同一 Claude session 打分,会有「我刚改的肯定更好」乐观偏差(SkillLens 实证 LLM-as-judge 准确率仅 46.4%)| 必须 spawn **独立子 agent**;keep/revert 走 **paired 比较**(同 judge 一次读改前+改后)的**奇数 N 多数决**,**不用绝对分数 delta**(绝对分跨 judge ±8 噪音、不可比) |
|
||||
| 1b | **拿绝对分数 delta 当 keep/revert 棘轮** | 绝对总分是抽样不是测量;baseline judge 与 rescore judge 用不同「标准尺」,差值大半是换尺、非真实质量变化(实测一支纯加标记的 skill 单评 −8.5、全是换尺)| 绝对分只做 triage 排名;keep/revert 用 paired 多数决,within-judge cancellation 消除换尺污染 |
|
||||
| 2 | **`git reset --hard` 当回滚** | 会丢工作树未提交改动;CI 历史断裂 | 用 `git revert HEAD` 创建反向 commit,保留可追溯链 |
|
||||
| 3 | **为凑分增冗余** | 触顶后继续硬改往往是「加废话/加段落让 LLM 觉得更详细」,实际质量不变 | 触顶信号(连续 2 轮 Δ<2 分)→ break 进 Phase 3,**见好就收** |
|
||||
| 4 | **跳过 test-prompts 直接评分** | 没有 test-prompts 的 dim8 是凭空打分,权重 23% 等于编造 | Phase 0.5 强制设计 2-3 prompts;若用户不给,默认编 3 个并展示确认 |
|
||||
| 5 | **轮内改多个维度** | 多变量同时变,分数升降无法归因到具体改动 | 每轮 1 个维度;相关簇(dim2/3/4)改其一时观察另两个是否跟涨 |
|
||||
| 6 | **dry_run 比例 > 30%** | dim8 实测维度形同虚设,分数虚高(早期 40 次记录 67% dry_run,0 revert) | 强制至少 1 个真实 full_test;dry_run 多的优化在 results.tsv 显式打 ⚠️ |
|
||||
| 7 | **静默跳过异常** | 遇到 git/tsv 异常时静默继续,破坏 ratchet 完整性 | 异常表 10 条 fallback 必须先告知用户再处理 |
|
||||
| 8 | **忽视维度相关性单独优化** | dim2/3/4 是相关簇,单独优化 dim2 时常发现已被前轮 dim3 修复推到顶 | 找最大加权短板维度时同时看相关簇短板,决定是否同步改 |
|
||||
|
||||
**触发场景**:每轮 Phase 2 改动前对照本表一次。任一反模式命中 → 改方案重写。
|
||||
|
||||
---
|
||||
|
||||
## 约束规则
|
||||
|
||||
1. **不改变skill的核心功能和用途** — 只优化"怎么写"和"怎么执行",不改"做什么"
|
||||
2. **不引入新依赖** — 不添加skill原本没有的scripts或references文件
|
||||
3. **每轮只改一个维度** — 避免多个变更导致无法归因
|
||||
4. **保持文件大小合理** — 优化后SKILL.md不应超过原始大小的150%
|
||||
5. **尊重花叔风格** — 中文为主、简洁为上
|
||||
6. **可回滚** — 所有改动在git分支上,用git revert而非reset --hard
|
||||
7. **评分独立性** — 效果维度必须用子agent或至少干跑验证,不能在同一上下文里「改完直接评」
|
||||
8. **Runtime 中立性** — skill 必须能在 Claude Code、Codex、Cursor、OpenClaw、Hermes 等任何 skills-compatible runtime 中正常运行。除非 skill 名明确绑定单一 runtime(如 `xxx-codex`、`huashu-slides-codex`),任何「在 Claude Code 里」「Claude Code skill」「单一 badge 钉死」「安装命令只给 `.claude/skills/` 一种路径」都视为 gate 不通过,须在 P0 优先修复(详见「Runtime 适配性审查」章节)
|
||||
|
||||
---
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 全量优化(推荐首次使用)
|
||||
```
|
||||
用户:"优化所有skills"
|
||||
→ Phase 0-3 完整流程
|
||||
→ 默认:先基线评估,按分数升序优先优化最低 5-10 个
|
||||
```
|
||||
|
||||
### 单个优化
|
||||
```
|
||||
用户:"优化 huashu-slides 这个skill"
|
||||
→ 只对指定skill执行 Phase 0.5-2
|
||||
```
|
||||
|
||||
### 仅评估不改
|
||||
```
|
||||
用户:"评估所有skills的质量"
|
||||
→ 只执行 Phase 0.5-1(设计测试prompt + 基线评估),不进入优化循环
|
||||
```
|
||||
|
||||
### 查看历史
|
||||
```
|
||||
用户:"看看skill优化历史"
|
||||
→ 读取并展示 results.tsv
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 设计灵感
|
||||
|
||||
> "You write the goals and constraints in program.md; let an agent generate and test code deltas indefinitely; keep only what measurably improves the objective."
|
||||
> — Karpathy, autoresearch
|
||||
|
||||
本skill的对应关系:
|
||||
- **program.md** → 本文件(评估rubric和约束规则)
|
||||
- **train.py** → 每个SKILL.md
|
||||
- **val_bpb** → ⚠️ **此处是 1.0 的概念错误源**:autoresearch 的 `val_bpb` 是**确定性 loss**(重跑同数),darwin 套到 **LLM-judge 分数(随机抽样)** 上却沿用「绝对值比大小」棘轮 → 不可重复的数当可重复用。修正:9 维 rubric 当 **paired 比较准则**、不当绝对 metric
|
||||
- **git ratchet** → 保留 paired 多数判「改后 ≥ 改前」的 commit(不是「绝对总分更高」的 commit)
|
||||
- **test set** → 每个skill的test-prompts.json
|
||||
|
||||
区别:增加了人在回路(autoresearch是全自主的,skill优化需要人的判断力),以及双重评估机制(结构+效果),因为skill的「好坏」比loss数值更微妙。
|
||||
|
||||
### 学术依据 & Credits
|
||||
|
||||
- **SkillLens**(arXiv [2605.23899](https://arxiv.org/abs/2605.23899)):9 维 rubric 的实证来源(LLM 自评 46.4% → 加 meta-skill 三维度后 73.8%)。
|
||||
- **SkillOpt**(arXiv [2605.23904](https://arxiv.org/abs/2605.23904)):validation-gated edits 形式化框架。代码 [github.com/microsoft/SkillOpt](https://github.com/microsoft/SkillOpt)(`pip install skillopt`)、项目页 [microsoft.github.io/SkillOpt](https://microsoft.github.io/SkillOpt/)。🤝 2026-06-03 微软官方仓库已把 darwin-skill 列入集成名单。
|
||||
- **autoresearch**:[github.com/karpathy/autoresearch](https://github.com/karpathy/autoresearch),本 skill 1.0 的原始灵感。
|
||||
|
||||
---
|
||||
|
||||
## 成果卡片生成(Result Card)
|
||||
|
||||
每个skill优化完成后(或全量汇总后),自动生成视觉成果卡片,截图保存为PNG。
|
||||
|
||||
### 卡片模板
|
||||
|
||||
模板位置:`templates/result-card.html`
|
||||
|
||||
3种风格,每次随机选择一种:
|
||||
|
||||
| 风格 | CSS类 | URL hash | 视觉特点 |
|
||||
|------|--------|----------|---------|
|
||||
| Warm Swiss | `.theme-swiss` | `#swiss` | 暖白底+赤陶橙,Inter字体,干净网格 |
|
||||
| Dark Terminal | `.theme-terminal` | `#terminal` | 近黑底+荧光绿,等宽字体,扫描线 |
|
||||
| Newspaper | `.theme-newspaper` | `#newspaper` | 暖白纸+深红,衬线字体,双栏编辑风 |
|
||||
|
||||
### 生成流程
|
||||
|
||||
```
|
||||
1. 复制 templates/result-card.html 到临时工作文件
|
||||
2. 用 sed/编辑工具 替换占位数据:
|
||||
- data-field="skill-name" → 实际skill名
|
||||
- data-field="score-before/after/delta" → 实际分数
|
||||
- 9个维度的 dim-bar-before/after width → 实际百分比(若模板仍是旧 8 维布局,加一行 dim9 反例黑名单条目)
|
||||
- data-field="improvement-1/2/3" → 实际改进摘要
|
||||
- data-field="date" → 当前日期
|
||||
3. 随机选择风格:hash 设为 swiss/terminal/newspaper 之一
|
||||
4. 用 scripts/screenshot.mjs 截图(2x 高清,只截 .card 元素,自动 open 图片):
|
||||
node .claude/skills/darwin-skill/scripts/screenshot.mjs \
|
||||
/abs/path/to/card.html /abs/path/to/output.png
|
||||
# 回退方案(脚本失败时):
|
||||
npx playwright screenshot "file:///path/to/card.html#[theme]" \
|
||||
output.png --viewport-size=960,1280 --wait-for-timeout=2000
|
||||
5. 提示用户查看成果卡片 PNG
|
||||
|
||||
### 资源文件速查
|
||||
|
||||
| 路径 | 用途 |
|
||||
|---|---|
|
||||
| `templates/result-card.html` | 3风格主模板(swiss/terminal/newspaper,hash切换) |
|
||||
| `templates/result-card-dark.html` / `-white.html` | 单一风格替代模板(需要锁定风格时用) |
|
||||
| `scripts/screenshot.mjs` | 2x 高清截图,只截 .card,自动 open |
|
||||
| `results.tsv` | 历次优化日志(9列含 eval_mode) |
|
||||
| `{skill目录}/test-prompts.json` | 每个 skill 的测试 prompt 集(用于维度8实测) |
|
||||
|
||||
### 何时生成
|
||||
|
||||
- **单skill卡片**:每个skill优化完成后,展示该skill的分数变化
|
||||
- **总览卡片**:全部优化完成后(Phase 3),展示全局战绩
|
||||
|
||||
### 品牌元素
|
||||
|
||||
- 顶部:Darwin.skill 品牌标识 + 日期
|
||||
- 底部:「Train your Skills like you train your models」+ github.com/alchaincyf/darwin-skill
|
||||
@@ -0,0 +1,68 @@
|
||||
# Runtime 适配性审查(详细对照表 + 扫描命令)
|
||||
|
||||
> SKILL.md 在「Runtime 适配性审查」章节会引用本文件。Phase 1 基线评估时跑红灯扫描需要查这里。
|
||||
|
||||
---
|
||||
|
||||
## 背景
|
||||
|
||||
花叔的 skills 基于 Anthropic 开放的 [Agent Skills](https://agentskills.io) 协议,应当能在 Claude Code、Codex、Cursor、OpenClaw、Hermes Agent、CodeBuddy、Workbuddy、Gemini CLI、OpenCode 等 50+ skills-compatible runtime 上通用。
|
||||
|
||||
这是 skill 分发力的根本——一个被误判为「单一 runtime 绑定」的 skill,会被其他 agent 直接拒绝安装(实例:nuwa-skill 因 README 写「在 Claude Code 里使用」被 Marvis agent 拒绝)。
|
||||
|
||||
**适用范围**:除非 skill 名字明确声明绑定单一 runtime(如 `huashu-slides-codex`、`xxx-for-claude-code`),所有 skill 必须通过本审查。
|
||||
|
||||
---
|
||||
|
||||
## 红灯信号(出现即扣分,必须在 P0 优化轮修复)
|
||||
|
||||
| 红灯类型 | 典型表现 | 危害 |
|
||||
|---|---|---|
|
||||
| Badge 钉死 | `[![Claude Code Skill]]`、`[![Cursor Only]]` 之类的单一 runtime badge | 视觉上首屏定调,其他 runtime 用户直接退出 |
|
||||
| 措辞钉死 | 「在 Claude Code 里」「Cursor 用户可以」「Codex 中使用」「Claude Code skill」 | 让 agent 解析时误判为"不是给我用的" |
|
||||
| 安装命令钉死 | 只给 `~/.claude/skills/` 路径、只给 `/plugin install`、只给某 runtime 私有 CLI | 不知道这是 Claude Code 命令的 agent 会拒绝 |
|
||||
| 工具调用钉死 | 工作流里硬编码 `mcp__claude-in-chrome__*`、`PostToolUse hook` 等单 runtime 能力,且不给替代方案 | 其他 runtime 没这些工具 → 流程跑不通 |
|
||||
| 路径硬编码 | `~/.claude/skills/xxx/`、`.claude/agents/yyy` 作为唯一路径 | 其他 runtime 用 `~/.cursor/skills/` `~/.codex/skills/` |
|
||||
|
||||
---
|
||||
|
||||
## 绿灯措辞(推荐改写)
|
||||
|
||||
| 红灯 | 绿灯 |
|
||||
|---|---|
|
||||
| "在 Claude Code 里" | "在你的 agent 里" / "在任何 skills-compatible runtime 中" |
|
||||
| "Claude Code skill" | "Agent Skill" |
|
||||
| "Claude Code 用户" | "skills-aware agent 用户" |
|
||||
| 单一 badge 钉死 | `Agent Skills Standard` + `skills.sh Compatible` + `Multi-Runtime` 三个中立 badge |
|
||||
| 只给 `npx skills add ...` 一行 | 三层结构:① 自动检测的一行命令 ② 折叠展开的各 runtime 手动路径 ③ 「作为参考资料 cat 进 context」fallback |
|
||||
| 工具名硬编码 | "用一个 browser automation 工具(例如 Claude 的 chrome MCP、Playwright 等)" |
|
||||
|
||||
---
|
||||
|
||||
## 例外清单(允许的「Claude Code 痕迹」)
|
||||
|
||||
不是所有 Claude-Code 相关字符都要清除。下面这些是**正当出现**的,不算红灯:
|
||||
|
||||
1. **Frontmatter `description` 里的中英文触发词**——这是 skill 入口,其他 runtime 解析 frontmatter 时同样能匹配
|
||||
2. **花叔生态内部联动的 skill 名引用**——如「调用 huashu-design」「跟 darwin-skill 配套」
|
||||
3. **明确标注的 runtime-specific 章节**——如「### 仅 Claude Code 优化(按需触发)」+ 解释清楚是 nice-to-have
|
||||
4. **commit message、changelog、内部脚本**——不属于用户读到的 skill 内容
|
||||
|
||||
---
|
||||
|
||||
## 审查时机
|
||||
|
||||
- **Phase 1 基线评估时**:每个 skill 跑一次红灯扫描,命中项以 `runtime_warn=N` 形式写入 results.tsv 的 `note` 列(不新增列、保持向后兼容)
|
||||
- **Phase 2 优化循环时**:红灯命中数 ≥ 1 的 skill,强制把第一轮优化方向定为 P0「runtime drift 修复」(详见 SKILL.md 优化策略库的 P0 章节),优先于其他维度
|
||||
- **Phase 3 汇总报告时**:单独一栏「runtime 中立度」展示修复进度(命中数从 X → 0)
|
||||
|
||||
---
|
||||
|
||||
## 红灯扫描快速命令
|
||||
|
||||
```bash
|
||||
# 在 skill 目录跑这个 grep,输出即红灯命中
|
||||
grep -nE "(在 Claude Code|Claude Code skill|Claude Code 用户|Cursor only|Codex 中|^\[!\[Claude Code|~/\.claude/skills/[a-z]|/plugin install\b)" SKILL.md README.md 2>/dev/null
|
||||
```
|
||||
|
||||
输出非空 = 该 skill 未通过 gate,必须在优化循环里修复。
|
||||
@@ -0,0 +1,142 @@
|
||||
# SkillLens 实证基线 + darwin-skill 本机验证数据
|
||||
|
||||
> SKILL.md 在「评估 Rubric」章节会引用本文件。需要查论文细节、controlled study 数据、HL 实战案例的具体数字时读这里。
|
||||
|
||||
---
|
||||
|
||||
## SkillLens 论文实证(外部证据)
|
||||
|
||||
**论文**:From Raw Experience to Skill Consumption: A Systematic Study of Model-Generated Agent Skills
|
||||
**作者**:Microsoft Research + 复旦大学 + 上海交大(16 作者)
|
||||
**arXiv**:2605.23899(2026-05-22,与 SkillOpt 同期发布)
|
||||
**实验规模**:5 domains(ALFWorld / SpreadsheetBench / SWE-bench-Verified / SEAL-0 / BFCL-v4)× 6 targets × 5 extractors
|
||||
|
||||
### 关键发现
|
||||
|
||||
1. **75% 案例 skill 有正收益,25% 出现 negative transfer**——即「加 skill 比不加还差」
|
||||
2. **强 agent 不一定是好 extractor**(Gemini-3.1-FL 在 skill 提取效率上反超 GPT-5.4)
|
||||
3. **LLM-as-judge 准确率仅 46.4%**——给 LLM judge 两份 skill,让它选哪份更好,**比扔硬币(50%)还差**
|
||||
4. **meta-skill rubric 把准确率提升到 73.8%**——加入三个维度:
|
||||
- **Failure-mechanism encoding**(必须显式编码失败模式)
|
||||
- **Actionable specificity**(禁止"考虑/可能"软化措辞)
|
||||
- **Risk-action blacklist**(必须有反例清单)
|
||||
5. 所有 domain 一致 +1.55pp 提升(meta-rubric 不是某个 domain 的特例)
|
||||
|
||||
### 对 darwin-skill 的意义
|
||||
|
||||
旧 8 维 rubric 全部由 LLM judge 打分 → 系统性乐观偏差 → 本机 results.tsv 早期 40 次 0 revert / 67% dry_run 印证。
|
||||
|
||||
v2 9 维 rubric 强化 dim3/dim5 + 新增 dim9 是 SkillLens 验证过的方向。**但即使 73.8%,每 4 次决策仍错 1 次——重要决策必须人审确认。**
|
||||
|
||||
---
|
||||
|
||||
## 本机 controlled study(2026-05-27)
|
||||
|
||||
### 实验设计
|
||||
|
||||
- **目标 skill**:huashu-research(170 行,独立度高)
|
||||
- **V1**:当前 GitHub 仓库最新版(被 darwin-skill 优化过 +33 分的版本)
|
||||
- **V2 (degraded)**:在 V1 基础上应用 4 类明确质量劣化:
|
||||
- **D1 模糊化具体指令**:「必须/立即」→「建议/可以根据情况」
|
||||
- **D2 删除关键检查点**:删掉 2 个 🔴 检查点
|
||||
- **D3 删掉异常处理表**:整段「## 异常处理」章节删除
|
||||
- **D4 插入 AI 腔废话**:在 Step 2、Step 3 插入花叔禁用词 9 个套话
|
||||
- **5 个独立 judge agent**(general-purpose subagent,无 context 共享)盲测打分
|
||||
- 一半 judge 先读 V1 后读 V2,另一半反序(去除位置偏差)
|
||||
|
||||
### 结果
|
||||
|
||||
| Judge | 顺序 | V1 总分 | V2 总分 | Δ | Verdict | Confidence |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | V1 → V2 | 89.5 | 41.7 | **+47.8** | V1>V2 | high |
|
||||
| 2 | V2 → V1 | 90.2 | 46.7 | **+43.5** | V1>V2 | high |
|
||||
| 3 | V1 → V2 | 89.5 | 37.6 | **+51.9** | V1>V2 | high |
|
||||
| 4 | V2 → V1 | 89.5 | 48.4 | **+41.1** | V1>V2 | high |
|
||||
| 5 | V1 → V2 | 89.5 | 41.4 | **+48.1** | V1>V2 | high |
|
||||
| **均值** | — | **89.6** | **43.2** | **+46.5** | **5/5 V1>V2** | **5/5 high** |
|
||||
|
||||
### 维度级共识
|
||||
|
||||
| 维度 | V1 均值 | V2 均值 | Δ | 一致性 |
|
||||
|---|---|---|---|---|
|
||||
| 1. Frontmatter | 9.0 | 5.6 | -3.4 | 全部识别 |
|
||||
| 2. 工作流清晰度 | 9.0 | 5.0 | -4.0 | 全部识别 |
|
||||
| 3. 边界条件覆盖 | 9.2 | 3.4 | -5.8 | **最明显劣化** |
|
||||
| 4. 检查点设计 | 9.0 | 2.6 | -6.4 | **最明显劣化** |
|
||||
| 5. 指令具体性 | 9.0 | 3.6 | -5.4 | 全部识别 |
|
||||
| 6. 资源整合度 | 8.0 | 6.8 | -1.2 | 弱 |
|
||||
| 7. 整体架构 | 9.0 | 4.6 | -4.4 | 全部识别 |
|
||||
| 8. 实测表现 | 9.0 | 3.6 | -5.4 | 全部识别 |
|
||||
|
||||
### 结论
|
||||
|
||||
**rubric 能识别 gross degradation(5/5 high confidence)**,但**这不能证明 fine-grained quality difference 也能识别**——SkillLens 的 46.4% 来自细粒度对比,darwin-skill 在细粒度判别上仍有失效风险。**重要决策仍需人审。**
|
||||
|
||||
---
|
||||
|
||||
## HL 实战 high-leverage 案例(来自 results.tsv 真实记录)
|
||||
|
||||
### HL-1:显性视觉标记是 dim4 的杠杆
|
||||
|
||||
**huashu-gpt-image Round 1**:红线 4 标题前加 🔴 CHECKPOINT + 「禁止交付」→「🛑 STOP」
|
||||
- 改动:4 行
|
||||
- dim4 变化:6.0 → 9.5(+3.5)
|
||||
- 单维度 ROI:每行改动 +0.875 分
|
||||
|
||||
**huashu-slide-codex r4**:路径优先级章节插入 🔴🔴🔴 默认路径锁定铁律
|
||||
- dim 总分 85 → 持平但避免了「Codex 自我合理化切 Path3 失败」实测翻车
|
||||
- 视觉锚是 LLM 解析的关键信号
|
||||
|
||||
### HL-2:if-then 三段式 fallback 表
|
||||
|
||||
**huashu-gpt-image Round 1**:新增「🛟 失败模式与 fallback 树」章节
|
||||
- 改动:3 张表 23 条三段式(触发条件 / 一线修复 / 仍失败兜底)
|
||||
- 单图失败 9 条
|
||||
- 批量生成 9 条
|
||||
- 生成执行层 5 条
|
||||
- dim3 变化:6.5 → 10(满分)
|
||||
|
||||
**huashu-weread-advisor edit-r2**:SKILL 加 11 行全局异常表 + 4 行数据展示规范 + 4 工作流各加 5-6 行 workflow 特有异常表
|
||||
- 共 ~33 个异常场景覆盖
|
||||
- dim 总分 81.3 → 87.6(+6.3)
|
||||
|
||||
### HL-3:维度相关性(dim2/3/4 是相关簇)
|
||||
|
||||
**huashu-gpt-image 实测**:
|
||||
- Round 1 攻 dim3(最低 6.5)→ 改成 10
|
||||
- 同期 dim2 自动从 7.5 → 9(未单独优化)
|
||||
- Round 2 试图单独攻 dim2 → 发现已触顶 9,多此一举
|
||||
- **教训**:找最低维度时同时看相关簇短板
|
||||
|
||||
### HL-4:触顶后边际收益递减
|
||||
|
||||
**huashu-gpt-image Round 2**:+0.15 marginal
|
||||
- Round 1: +10.7 分(基线 80.8 → 91.5)
|
||||
- Round 2: +0.15 分(91.5 → 91.65)
|
||||
- **触顶信号**:连续 2 轮 Δ < 2 → break,避免过度优化
|
||||
|
||||
**对比 darwin-skill 早期**:40 次记录 0 revert,部分是因为没有触顶规则,硬凑 MAX_ROUNDS=3 都 keep 了边际改动。
|
||||
|
||||
---
|
||||
|
||||
## 历史 results.tsv 优化记录摘要(截至 2026-05-27)
|
||||
|
||||
完整记录见 `results.tsv`。
|
||||
|
||||
| skill | 起分 | 终分 | Δ | 模式 |
|
||||
|---|---|---|---|---|
|
||||
| huashu-research | 40.0 | 73.2 | +33.2 | dry_run |
|
||||
| huashu-video-check | 72.1 | 80.5 | +8.4 | dry_run |
|
||||
| harness-optimizer | 78.4 | 86.0 | +7.6 | dry_run |
|
||||
| freud-skill | 72.5 | 86.0 | +13.5 | dry_run |
|
||||
| **claude-design** | **74.5** | **91.0** | **+16.5** | **full_test ✅** |
|
||||
| huashu-design | 62.3 | 86.7 | +24.4 | dry_run |
|
||||
| huashu-weread-advisor | 76.5 | 91.4 | +14.9 | full_test_informed ✅ |
|
||||
| huashu-slide-codex | 82.6 | 85+ | +2~ | mixed |
|
||||
| **huashu-gpt-image** | **80.8** | **91.65** | **+10.85** | **full_test ✅(v2 实战)** |
|
||||
| **darwin-skill (self-fix)** | **86.05** | **92.05** | **+6.0** | **full_test ✅(自指闭环)** |
|
||||
|
||||
**统计**:
|
||||
- 平均提升:~+13.5 分
|
||||
- 全部 keep(v1 时代 0 revert 印证 rubric 偏松;v2 引入触顶 break 规则)
|
||||
- full_test 比例:从 33% 提升到 100%(最近 2 次都是 full_test)
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Darwin Skill - 高清截图脚本
|
||||
*
|
||||
* 用法: node scripts/screenshot.mjs [html文件路径] [输出png路径]
|
||||
*
|
||||
* 特性:
|
||||
* - 2x deviceScaleFactor,输出高清图
|
||||
* - 只截 .card 元素,无多余背景
|
||||
* - 等待字体加载完成
|
||||
* - 截完自动用 open 命令打开图片
|
||||
*/
|
||||
|
||||
import { createRequire } from 'module';
|
||||
import { execSync } from 'child_process';
|
||||
import { existsSync } from 'fs';
|
||||
import path from 'path';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
// 健壮解析 playwright / playwright-core:跨机器、跨平台,不硬编码任何用户路径
|
||||
function loadPlaywright() {
|
||||
// 1) 标准解析(脚本目录或 NODE_PATH 里有的话)
|
||||
for (const m of ['playwright', 'playwright-core']) {
|
||||
try { return require(m); } catch {}
|
||||
}
|
||||
// 2) 动态定位全局 node_modules 并尝试候选路径
|
||||
const candidates = [];
|
||||
try {
|
||||
const groot = execSync('npm root -g', { encoding: 'utf8' }).trim();
|
||||
candidates.push(path.join(groot, 'playwright-core'));
|
||||
candidates.push(path.join(groot, 'playwright'));
|
||||
// openclaw 等把 playwright-core 作为嵌套依赖的情况
|
||||
candidates.push(path.join(groot, 'openclaw', 'node_modules', 'playwright-core'));
|
||||
} catch {}
|
||||
for (const c of candidates) {
|
||||
if (existsSync(c)) { try { return require(c); } catch {} }
|
||||
}
|
||||
throw new Error(
|
||||
'playwright/playwright-core 未找到。请先安装:npm install -g playwright-core 且 npx playwright install chromium'
|
||||
);
|
||||
}
|
||||
const pw = loadPlaywright();
|
||||
|
||||
const htmlPath = process.argv[2] || new URL('../templates/result-card.html', import.meta.url).pathname;
|
||||
const outputPath = process.argv[3] || new URL('../templates/result-card.png', import.meta.url).pathname;
|
||||
|
||||
async function screenshot() {
|
||||
const browser = await pw.chromium.launch();
|
||||
|
||||
try {
|
||||
const context = await browser.newContext({
|
||||
viewport: { width: 920, height: 1600 },
|
||||
deviceScaleFactor: 2,
|
||||
});
|
||||
|
||||
const page = await context.newPage();
|
||||
|
||||
await page.goto(`file://${htmlPath.replace(/\\/g,'/')}`, { waitUntil: 'networkidle' });
|
||||
|
||||
// 等待字体加载
|
||||
await page.evaluate(() => document.fonts.ready);
|
||||
// 额外等待确保渲染完成
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 只截 .card 元素
|
||||
const card = await page.locator('.card');
|
||||
await card.screenshot({
|
||||
path: outputPath,
|
||||
type: 'png',
|
||||
});
|
||||
|
||||
console.log(`截图完成: ${outputPath}`);
|
||||
|
||||
// 获取图片尺寸信息
|
||||
const box = await card.boundingBox();
|
||||
console.log(`卡片尺寸: ${Math.round(box.width)}x${Math.round(box.height)}px (CSS)`);
|
||||
console.log(`输出尺寸: ${Math.round(box.width * 2)}x${Math.round(box.height * 2)}px (2x高清)`);
|
||||
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
// 自动打开图片(跨平台)
|
||||
try {
|
||||
if (process.platform === 'win32') {
|
||||
execSync(`start "" "${outputPath}"`);
|
||||
} else if (process.platform === 'darwin') {
|
||||
execSync(`open "${outputPath}"`);
|
||||
} else {
|
||||
execSync(`xdg-open "${outputPath}"`);
|
||||
}
|
||||
} catch {
|
||||
// 打不开也无妨,路径已打印
|
||||
console.log(`图片已保存: ${outputPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
screenshot().catch(err => {
|
||||
console.error('截图失败:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,698 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Darwin Skill - 暗夜成就</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
min-height: 100vh;
|
||||
background: #0D0D0F;
|
||||
font-family: 'Noto Sans SC', 'Inter', sans-serif;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 900px;
|
||||
min-height: 600px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #0D0D0F;
|
||||
color: #FFFFFF;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 全局光效底层 ===== */
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, rgba(232,89,12,0.12) 0%, rgba(232,89,12,0.04) 35%, transparent 70%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.card > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* ===== 1. 顶部品牌条 ===== */
|
||||
.brand-bar {
|
||||
padding: 24px 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
.brand-name {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
letter-spacing: 0.02em;
|
||||
font-family: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
.brand-name .dot { color: #E8590C; }
|
||||
.brand-date {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
/* ===== 2. 成就徽章区(视觉焦点) ===== */
|
||||
.achievement-section {
|
||||
padding: 36px 48px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 徽章容器 */
|
||||
.badge-container {
|
||||
position: relative;
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 外圈光晕 */
|
||||
.badge-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: -30px;
|
||||
right: -30px;
|
||||
bottom: -30px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(232,89,12,0.25) 0%, rgba(255,107,53,0.08) 50%, transparent 75%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.badge-svg {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
filter: drop-shadow(0 0 30px rgba(232,89,12,0.35)) drop-shadow(0 0 60px rgba(232,89,12,0.15));
|
||||
}
|
||||
|
||||
.badge-ring-bg {
|
||||
fill: none;
|
||||
stroke: rgba(255,255,255,0.06);
|
||||
stroke-width: 14;
|
||||
}
|
||||
.badge-ring-glow {
|
||||
fill: none;
|
||||
stroke: url(#darkOrangeGradient);
|
||||
stroke-width: 16;
|
||||
stroke-linecap: round;
|
||||
/* 周长 = 2 * PI * 85 ≈ 534, 87% → dashoffset = 534 * 0.13 ≈ 69 */
|
||||
stroke-dasharray: 534;
|
||||
stroke-dashoffset: 69;
|
||||
transform: rotate(-90deg);
|
||||
transform-origin: center;
|
||||
}
|
||||
.badge-ring-track {
|
||||
fill: none;
|
||||
stroke: rgba(255,255,255,0.03);
|
||||
stroke-width: 14;
|
||||
stroke-dasharray: 6 6;
|
||||
}
|
||||
|
||||
.badge-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
.badge-score {
|
||||
font-size: 80px;
|
||||
font-weight: 900;
|
||||
color: #FFFFFF;
|
||||
line-height: 1;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: -0.04em;
|
||||
text-shadow: 0 0 40px rgba(232,89,12,0.4);
|
||||
}
|
||||
.badge-max {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
font-family: 'Inter', sans-serif;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.badge-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.achievement-title {
|
||||
font-size: 30px;
|
||||
font-weight: 900;
|
||||
line-height: 1.3;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.achievement-skill {
|
||||
color: #FF6B35;
|
||||
text-shadow: 0 0 20px rgba(232,89,12,0.3);
|
||||
}
|
||||
.achievement-subtitle {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
/* ===== 3. 经验条区 ===== */
|
||||
.xp-section {
|
||||
padding: 28px 48px 32px;
|
||||
}
|
||||
.xp-bar-wrapper {
|
||||
background: rgba(255,255,255,0.04);
|
||||
border-radius: 16px;
|
||||
padding: 24px 28px;
|
||||
}
|
||||
.xp-labels {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.xp-old {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: #444;
|
||||
}
|
||||
.xp-new {
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #FFFFFF;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
.xp-track {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: 10px;
|
||||
overflow: visible;
|
||||
}
|
||||
.xp-fill {
|
||||
height: 100%;
|
||||
width: 87%;
|
||||
background: linear-gradient(90deg, #E8590C 0%, #FF6B35 100%);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px rgba(232,89,12,0.4), 0 0 6px rgba(232,89,12,0.6);
|
||||
position: relative;
|
||||
}
|
||||
.xp-delta-badge {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
right: -8px;
|
||||
background: linear-gradient(135deg, #E8590C, #FF6B35);
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
font-family: 'Inter', sans-serif;
|
||||
padding: 4px 14px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 16px rgba(232,89,12,0.4);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.xp-delta-badge::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid #FF6B35;
|
||||
}
|
||||
|
||||
/* ===== 4. 最大突破卡片 ===== */
|
||||
.breakthrough-section {
|
||||
padding: 0 48px 20px;
|
||||
}
|
||||
.breakthrough-card {
|
||||
position: relative;
|
||||
border-radius: 16px;
|
||||
padding: 28px 32px;
|
||||
background: rgba(255,255,255,0.03);
|
||||
overflow: hidden;
|
||||
}
|
||||
/* 渐变边框效果 */
|
||||
.breakthrough-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 16px;
|
||||
padding: 2px;
|
||||
background: linear-gradient(135deg, #E8590C 0%, #FF6B35 40%, rgba(255,107,53,0.2) 100%);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
.breakthrough-label {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
color: #FF6B35;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.breakthrough-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
.breakthrough-scores {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.bt-from {
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
color: #444;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: #444;
|
||||
}
|
||||
.bt-arrow {
|
||||
font-size: 20px;
|
||||
color: #555;
|
||||
}
|
||||
.bt-to {
|
||||
font-size: 52px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #FF6B35;
|
||||
line-height: 1;
|
||||
text-shadow: 0 0 24px rgba(232,89,12,0.3);
|
||||
}
|
||||
.bt-pct {
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #4ADE80;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.breakthrough-text {
|
||||
flex: 1;
|
||||
}
|
||||
.bt-dim-name {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.bt-story {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #777;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ===== 5. 维度网格 2x4 ===== */
|
||||
.dims-section {
|
||||
padding: 0 48px 16px;
|
||||
}
|
||||
.dims-header {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #555;
|
||||
letter-spacing: 0.1em;
|
||||
margin-bottom: 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.dims-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.dim-cell {
|
||||
background: rgba(255,255,255,0.04);
|
||||
border-radius: 12px;
|
||||
padding: 16px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
position: relative;
|
||||
border: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
.dim-cell.hot {
|
||||
background: rgba(232,89,12,0.08);
|
||||
border: 1px solid rgba(232,89,12,0.2);
|
||||
box-shadow: 0 0 20px rgba(232,89,12,0.1);
|
||||
}
|
||||
.dim-cell.warm {
|
||||
background: rgba(255,255,255,0.05);
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
.dim-name {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.dim-cell.hot .dim-name {
|
||||
color: #888;
|
||||
}
|
||||
.dim-score-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
}
|
||||
.dim-old-score {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #444;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: #444;
|
||||
}
|
||||
.dim-score {
|
||||
font-size: 30px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #FFFFFF;
|
||||
line-height: 1;
|
||||
}
|
||||
.dim-cell.hot .dim-score {
|
||||
color: #FF6B35;
|
||||
text-shadow: 0 0 12px rgba(232,89,12,0.3);
|
||||
}
|
||||
.dim-arrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
font-family: 'Inter', sans-serif;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
line-height: 1;
|
||||
}
|
||||
.dim-arrow.up-big {
|
||||
background: rgba(232,89,12,0.9);
|
||||
color: #fff;
|
||||
box-shadow: 0 0 8px rgba(232,89,12,0.3);
|
||||
}
|
||||
.dim-arrow.up-mid {
|
||||
background: rgba(232,89,12,0.2);
|
||||
color: #FF6B35;
|
||||
}
|
||||
.dim-arrow.up-small {
|
||||
background: rgba(74,222,128,0.12);
|
||||
color: #4ADE80;
|
||||
}
|
||||
|
||||
/* ===== 6. 改进摘要 ===== */
|
||||
.summary-section {
|
||||
padding: 0 48px 32px;
|
||||
}
|
||||
.summary-header {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #555;
|
||||
letter-spacing: 0.1em;
|
||||
margin-bottom: 14px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.summary-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.summary-item {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #888;
|
||||
line-height: 1.6;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
.summary-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 9px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #E8590C;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 8px rgba(232,89,12,0.5);
|
||||
}
|
||||
|
||||
/* ===== 7. 底部品牌条 ===== */
|
||||
.footer {
|
||||
margin-top: auto;
|
||||
padding: 28px 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
.footer-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.footer-brand {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
font-family: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
.footer-brand .dot { color: #E8590C; }
|
||||
.footer-slogan {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
font-weight: 500;
|
||||
}
|
||||
.footer-right {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.footer-url {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
font-family: 'Inter', monospace;
|
||||
font-weight: 600;
|
||||
}
|
||||
.footer-by {
|
||||
font-size: 13px;
|
||||
color: #444;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<!-- 1. 顶部品牌条 -->
|
||||
<div class="brand-bar">
|
||||
<div class="brand-name">Darwin<span class="dot">.</span>skill</div>
|
||||
<div class="brand-date" data-field="date">2026.04.14</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 成就徽章区 -->
|
||||
<div class="achievement-section">
|
||||
<div class="badge-container">
|
||||
<svg class="badge-svg" viewBox="0 0 200 200">
|
||||
<defs>
|
||||
<linearGradient id="darkOrangeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#E8590C"/>
|
||||
<stop offset="100%" stop-color="#FF6B35"/>
|
||||
</linearGradient>
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- 底层虚线轨道 -->
|
||||
<circle cx="100" cy="100" r="85" class="badge-ring-track"/>
|
||||
<!-- 背景环 -->
|
||||
<circle cx="100" cy="100" r="85" class="badge-ring-bg"/>
|
||||
<!-- 发光进度环 -->
|
||||
<circle cx="100" cy="100" r="85" class="badge-ring-glow" filter="url(#glow)"/>
|
||||
</svg>
|
||||
<div class="badge-center">
|
||||
<div>
|
||||
<span class="badge-score" data-field="score-after">87</span><span class="badge-max">/100</span>
|
||||
</div>
|
||||
<div class="badge-label">质量总分</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="achievement-title">
|
||||
我的Skill进化报告<br>
|
||||
<span class="achievement-skill" data-field="skill-name">审校降AI味</span>
|
||||
</div>
|
||||
<div class="achievement-subtitle" data-field="skill-id">huashu-proofreading</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 经验条 -->
|
||||
<div class="xp-section">
|
||||
<div class="xp-bar-wrapper">
|
||||
<div class="xp-labels">
|
||||
<span class="xp-old" data-field="score-before">72</span>
|
||||
<span class="xp-new" data-field="score-after-2">87</span>
|
||||
</div>
|
||||
<div class="xp-track">
|
||||
<div class="xp-fill">
|
||||
<div class="xp-delta-badge" data-field="score-delta">+15</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 最大突破 -->
|
||||
<div class="breakthrough-section">
|
||||
<div class="breakthrough-card">
|
||||
<div class="breakthrough-label">最大突破</div>
|
||||
<div class="breakthrough-content">
|
||||
<div class="breakthrough-scores">
|
||||
<span class="bt-from" data-field="top1-from">5</span>
|
||||
<span class="bt-arrow">→</span>
|
||||
<span class="bt-to" data-field="top1-to">9</span>
|
||||
<span class="bt-pct" data-field="top1-pct">+80%</span>
|
||||
</div>
|
||||
<div class="breakthrough-text">
|
||||
<div class="bt-dim-name" data-field="top1-name">指令精度</div>
|
||||
<div class="bt-story" data-field="top1-story">从模糊指令到精确可执行,指令精度翻了将近一倍</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 八维度网格 -->
|
||||
<div class="dims-section">
|
||||
<div class="dims-header">八维度全景</div>
|
||||
<div class="dims-grid">
|
||||
<div class="dim-cell warm">
|
||||
<div class="dim-name">元数据</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-mid">+2</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">工作流</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">边界覆盖</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">4</span>
|
||||
<span class="dim-score">7</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">检查点</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">7</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-small">+1</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">指令精度</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">9</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+4</span>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">资源整合</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">7</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-small">+1</span>
|
||||
</div>
|
||||
<div class="dim-cell warm">
|
||||
<div class="dim-name">整体架构</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-mid">+2</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">实测表现</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 改进摘要 -->
|
||||
<div class="summary-section">
|
||||
<div class="summary-header">关键改进</div>
|
||||
<div class="summary-items">
|
||||
<div class="summary-item" data-field="improve-1">补充异常处理fallback路径,边界覆盖从4飙升到7</div>
|
||||
<div class="summary-item" data-field="improve-2">工作流重组为线性可执行步骤,每步可验证</div>
|
||||
<div class="summary-item" data-field="improve-3">测试prompt覆盖率从60%提升到95%,实测表现大幅进化</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 7. 底部品牌条 -->
|
||||
<div class="footer">
|
||||
<div class="footer-left">
|
||||
<div class="footer-brand">Darwin<span class="dot">.</span>skill</div>
|
||||
<div class="footer-slogan">像训练模型一样进化你的Skills</div>
|
||||
</div>
|
||||
<div class="footer-right">
|
||||
<div class="footer-url">github.com/alchaincyf/darwin-skill</div>
|
||||
<div class="footer-by">by 花叔</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,444 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Darwin Skill - 我的Skill进化报告(白金版)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Noto+Sans+SC:wght@300;400;500;700;900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
min-height: 100vh;
|
||||
background: #FFFFFF;
|
||||
font-family: 'Noto Sans SC', 'Inter', sans-serif;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 900px;
|
||||
min-height: 600px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #FFFFFF;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
/* ===== 金色渐变工具 ===== */
|
||||
.gold-text {
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520, #B8860B);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.gold-line {
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, #B8860B, #DAA520, #B8860B);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ===== 1. 顶部极简品牌 ===== */
|
||||
.top-bar {
|
||||
padding: 32px 56px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.top-brand {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #CCCCCC;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.top-date {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #CCCCCC;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
.top-line {
|
||||
margin: 20px 56px 0;
|
||||
}
|
||||
|
||||
/* ===== 2. 核心成就区 ===== */
|
||||
.hero {
|
||||
padding: 56px 56px 0;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
letter-spacing: 0.12em;
|
||||
}
|
||||
.hero-skill-name {
|
||||
font-size: 48px;
|
||||
font-weight: 900;
|
||||
color: #1A1A1A;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
/* 超大分数显示 */
|
||||
.score-display {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.score-from {
|
||||
font-size: 80px;
|
||||
font-weight: 300;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #E8E8E8;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
.score-arrow {
|
||||
display: inline-block;
|
||||
width: 48px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, #B8860B, #DAA520);
|
||||
position: relative;
|
||||
top: -30px;
|
||||
}
|
||||
.score-arrow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: -5px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid #DAA520;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
}
|
||||
.score-to {
|
||||
font-size: 128px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.05em;
|
||||
}
|
||||
|
||||
.delta-display {
|
||||
display: inline-block;
|
||||
font-size: 48px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: -0.02em;
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520, #B8860B);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* ===== 3. 金色分割线 ===== */
|
||||
.divider {
|
||||
margin: 36px 56px 0;
|
||||
}
|
||||
|
||||
/* ===== 4. 最大突破区 ===== */
|
||||
.breakthrough {
|
||||
padding: 40px 56px 0;
|
||||
text-align: left;
|
||||
}
|
||||
.breakthrough-label {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
margin-bottom: 12px;
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.breakthrough-dim {
|
||||
font-size: 36px;
|
||||
font-weight: 900;
|
||||
color: #1A1A1A;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.breakthrough-score-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 14px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.breakthrough-from {
|
||||
font-size: 48px;
|
||||
font-weight: 300;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #E0E0E0;
|
||||
line-height: 1;
|
||||
}
|
||||
.breakthrough-mini-arrow {
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, #B8860B, #DAA520);
|
||||
position: relative;
|
||||
top: -16px;
|
||||
}
|
||||
.breakthrough-mini-arrow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: -4px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid #DAA520;
|
||||
border-top: 5px solid transparent;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
.breakthrough-to {
|
||||
font-size: 64px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
}
|
||||
.breakthrough-pct {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
font-family: 'Inter', sans-serif;
|
||||
margin-left: 4px;
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.breakthrough-story {
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 1.6;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ===== 5. 维度网格 ===== */
|
||||
.dims {
|
||||
padding: 40px 56px 0;
|
||||
text-align: left;
|
||||
}
|
||||
.dims-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 0;
|
||||
}
|
||||
.dim-cell {
|
||||
padding: 20px 16px;
|
||||
border-bottom: 1px solid #F0F0F0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
/* 右边框:每行前3个有 */
|
||||
.dim-cell:nth-child(4n+1),
|
||||
.dim-cell:nth-child(4n+2),
|
||||
.dim-cell:nth-child(4n+3) {
|
||||
border-right: 1px solid #F0F0F0;
|
||||
}
|
||||
/* 最后一行去掉底边框 */
|
||||
.dim-cell:nth-child(n+5) {
|
||||
border-bottom: none;
|
||||
}
|
||||
.dim-name {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #999999;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.dim-score-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
}
|
||||
.dim-score {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #1A1A1A;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -0.03em;
|
||||
}
|
||||
.dim-delta {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* ===== 6. 底部 ===== */
|
||||
.footer-line {
|
||||
margin: 48px 56px 0;
|
||||
}
|
||||
.footer {
|
||||
padding: 20px 56px 32px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.footer-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
.footer-brand {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #CCCCCC;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.footer-brand .dot {
|
||||
background: linear-gradient(135deg, #B8860B, #DAA520);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.footer-slogan {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #CCCCCC;
|
||||
}
|
||||
.footer-url {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #CCCCCC;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<!-- 1. 顶部极简品牌 -->
|
||||
<div class="top-bar">
|
||||
<div class="top-brand">Darwin.skill</div>
|
||||
<div class="top-date" data-field="date">2026.04.14</div>
|
||||
</div>
|
||||
<div class="gold-line top-line"></div>
|
||||
|
||||
<!-- 2. 核心成就区 -->
|
||||
<div class="hero">
|
||||
<div class="hero-subtitle">我的Skill进化报告</div>
|
||||
<div class="hero-skill-name" data-field="skill-name">审校降AI味</div>
|
||||
<div class="score-display">
|
||||
<span class="score-from" data-field="score-before">72</span>
|
||||
<span class="score-arrow"></span>
|
||||
<span class="score-to" data-field="score-after">87</span>
|
||||
</div>
|
||||
<div class="delta-display" data-field="score-delta">+15</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 金色分割线 -->
|
||||
<div class="gold-line divider"></div>
|
||||
|
||||
<!-- 4. 最大突破 -->
|
||||
<div class="breakthrough">
|
||||
<div class="breakthrough-label">最大突破</div>
|
||||
<div class="breakthrough-dim" data-field="top1-name">指令精度</div>
|
||||
<div class="breakthrough-score-row">
|
||||
<span class="breakthrough-from" data-field="top1-from">5</span>
|
||||
<span class="breakthrough-mini-arrow"></span>
|
||||
<span class="breakthrough-to" data-field="top1-to">9</span>
|
||||
<span class="breakthrough-pct" data-field="top1-pct">+80%</span>
|
||||
</div>
|
||||
<div class="breakthrough-story" data-field="top1-story">从模糊指令到精确可执行,指令精度翻了将近一倍</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 维度网格 -->
|
||||
<div class="dims">
|
||||
<div class="dims-grid">
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">元数据</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">8</span>
|
||||
<span class="dim-delta">▲ +2</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">工作流</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">8</span>
|
||||
<span class="dim-delta">▲ +3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">边界覆盖</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">7</span>
|
||||
<span class="dim-delta">▲ +3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">检查点</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">7</span>
|
||||
<span class="dim-delta">▲ +1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">指令精度</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">9</span>
|
||||
<span class="dim-delta">▲ +4</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">资源整合</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">8</span>
|
||||
<span class="dim-delta">▲ +1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">整体架构</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">8</span>
|
||||
<span class="dim-delta">▲ +2</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">实测表现</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-score">8</span>
|
||||
<span class="dim-delta">▲ +3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 底部 -->
|
||||
<div class="gold-line footer-line"></div>
|
||||
<div class="footer">
|
||||
<div class="footer-left">
|
||||
<div class="footer-brand">Darwin<span class="dot">.</span>skill</div>
|
||||
<div class="footer-slogan">像训练模型一样进化你的Skills</div>
|
||||
</div>
|
||||
<div class="footer-url">github.com/alchaincyf/darwin-skill</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,616 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Darwin Skill - 我的Skill进化报告</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
min-height: 100vh;
|
||||
background: #FAFAF5;
|
||||
font-family: 'Noto Sans SC', 'Inter', sans-serif;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 900px;
|
||||
min-height: 600px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #FAFAF5;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
/* ===== 1. 顶部品牌条 ===== */
|
||||
.brand-bar {
|
||||
background: #1A1A1A;
|
||||
padding: 24px 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.brand-name {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
letter-spacing: 0.02em;
|
||||
font-family: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
.brand-name .dot { color: #E8590C; }
|
||||
.brand-date {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #888;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
/* ===== 2. 核心成就区 ===== */
|
||||
.hero-section {
|
||||
padding: 40px 48px 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 48px;
|
||||
background: linear-gradient(180deg, #FAFAF5 0%, #F5F0E8 100%);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* SVG圆环 */
|
||||
.ring-container {
|
||||
flex-shrink: 0;
|
||||
width: 280px;
|
||||
height: 280px;
|
||||
position: relative;
|
||||
}
|
||||
.ring-bg {
|
||||
fill: none;
|
||||
stroke: #E8E0D4;
|
||||
stroke-width: 16;
|
||||
stroke-dasharray: 8 8;
|
||||
}
|
||||
.ring-progress {
|
||||
fill: none;
|
||||
stroke: url(#orangeGradient);
|
||||
stroke-width: 18;
|
||||
stroke-linecap: round;
|
||||
stroke-dasharray: 534;
|
||||
stroke-dashoffset: 69;
|
||||
transform: rotate(-90deg);
|
||||
transform-origin: center;
|
||||
filter: drop-shadow(0 2px 8px rgba(232,89,12,0.3));
|
||||
}
|
||||
.ring-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
}
|
||||
.ring-score {
|
||||
font-size: 88px;
|
||||
font-weight: 900;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
.ring-max {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #B0A898;
|
||||
font-family: 'Inter', sans-serif;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.ring-label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #999;
|
||||
margin-top: 4px;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
/* 右侧文字区 */
|
||||
.hero-text {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
line-height: 1.25;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.hero-skill-name {
|
||||
color: #E8590C;
|
||||
}
|
||||
.hero-journey {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.hero-journey strong {
|
||||
color: #1A1A1A;
|
||||
font-weight: 700;
|
||||
}
|
||||
.delta-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: #E8590C;
|
||||
color: #fff;
|
||||
padding: 10px 28px;
|
||||
border-radius: 12px;
|
||||
font-size: 42px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
letter-spacing: -0.02em;
|
||||
width: fit-content;
|
||||
box-shadow: 0 4px 16px rgba(232,89,12,0.3);
|
||||
}
|
||||
.delta-badge-label {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
opacity: 0.9;
|
||||
font-family: 'Noto Sans SC', sans-serif;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* ===== 3. 最大突破区 ===== */
|
||||
.breakthrough-section {
|
||||
padding: 0 48px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
.breakthrough-card {
|
||||
flex: 1;
|
||||
border-radius: 16px;
|
||||
padding: 28px 28px 24px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.breakthrough-card.primary {
|
||||
background: linear-gradient(135deg, #E8590C 0%, #FF8A4C 100%);
|
||||
color: #fff;
|
||||
flex: 1.2;
|
||||
}
|
||||
.breakthrough-card.secondary {
|
||||
background: #F0EAE0;
|
||||
color: #1A1A1A;
|
||||
border: 2px solid #E0D8CC;
|
||||
}
|
||||
.breakthrough-label {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.breakthrough-card.primary .breakthrough-label {
|
||||
color: rgba(255,255,255,0.75);
|
||||
}
|
||||
.breakthrough-card.secondary .breakthrough-label {
|
||||
color: #999;
|
||||
}
|
||||
.breakthrough-dim {
|
||||
font-size: 24px;
|
||||
font-weight: 900;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.breakthrough-score-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.breakthrough-from {
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
opacity: 0.5;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-decoration: line-through;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
.breakthrough-arrow {
|
||||
font-size: 20px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.breakthrough-to {
|
||||
font-size: 52px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
line-height: 1;
|
||||
}
|
||||
.breakthrough-card.secondary .breakthrough-to {
|
||||
color: #E8590C;
|
||||
}
|
||||
.breakthrough-pct {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
.breakthrough-card.primary .breakthrough-pct {
|
||||
color: rgba(255,255,255,0.85);
|
||||
}
|
||||
.breakthrough-card.secondary .breakthrough-pct {
|
||||
color: #2B8A3E;
|
||||
}
|
||||
.breakthrough-story {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.breakthrough-card.primary .breakthrough-story {
|
||||
color: rgba(255,255,255,0.9);
|
||||
}
|
||||
.breakthrough-card.secondary .breakthrough-story {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* ===== 4. 全维度速览 ===== */
|
||||
.dims-section {
|
||||
padding: 32px 48px 0;
|
||||
}
|
||||
.dims-header {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #999;
|
||||
letter-spacing: 0.08em;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.dims-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.dim-cell {
|
||||
background: #F0EBE3;
|
||||
border-radius: 12px;
|
||||
padding: 16px 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
position: relative;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.dim-cell.hot {
|
||||
background: #FFF0E6;
|
||||
border: 2px solid rgba(232,89,12,0.2);
|
||||
}
|
||||
.dim-cell.warm {
|
||||
background: #F5EEE4;
|
||||
}
|
||||
.dim-name {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #888;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.dim-score-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
}
|
||||
.dim-score {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
font-family: 'Inter', sans-serif;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
}
|
||||
.dim-cell.hot .dim-score {
|
||||
color: #E8590C;
|
||||
}
|
||||
.dim-old-score {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #BBB;
|
||||
font-family: 'Inter', sans-serif;
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: #CCC;
|
||||
}
|
||||
.dim-arrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
font-family: 'Inter', sans-serif;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
line-height: 1;
|
||||
}
|
||||
.dim-arrow.up-big {
|
||||
background: #E8590C;
|
||||
color: #fff;
|
||||
}
|
||||
.dim-arrow.up-mid {
|
||||
background: rgba(232,89,12,0.15);
|
||||
color: #E8590C;
|
||||
}
|
||||
.dim-arrow.up-small {
|
||||
background: rgba(43,138,62,0.1);
|
||||
color: #2B8A3E;
|
||||
}
|
||||
|
||||
/* ===== 5. 改进摘要 ===== */
|
||||
.summary-section {
|
||||
padding: 28px 48px 0;
|
||||
}
|
||||
.summary-header {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #999;
|
||||
letter-spacing: 0.08em;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.summary-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.summary-item {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
line-height: 1.6;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
.summary-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 9px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #E8590C;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* ===== 6. 底部品牌区 ===== */
|
||||
.footer {
|
||||
margin-top: auto;
|
||||
background: #1A1A1A;
|
||||
padding: 28px 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.footer-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.footer-brand {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
font-family: 'Inter', 'Noto Sans SC', sans-serif;
|
||||
}
|
||||
.footer-brand .dot { color: #E8590C; }
|
||||
.footer-slogan {
|
||||
font-size: 14px;
|
||||
color: #777;
|
||||
font-weight: 500;
|
||||
}
|
||||
.footer-right {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.footer-url {
|
||||
font-size: 14px;
|
||||
color: #aaa;
|
||||
font-family: 'Inter', monospace;
|
||||
font-weight: 600;
|
||||
}
|
||||
.footer-by {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 装饰性纹理 */
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
background: radial-gradient(circle at top right, rgba(232,89,12,0.04) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.card > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<!-- 1. 顶部品牌条 -->
|
||||
<div class="brand-bar">
|
||||
<div class="brand-name">Darwin<span class="dot">.</span>skill</div>
|
||||
<div class="brand-date" data-field="date">2026.04.14</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 核心成就区 -->
|
||||
<div class="hero-section">
|
||||
<div class="ring-container">
|
||||
<svg viewBox="0 0 200 200" width="280" height="280">
|
||||
<defs>
|
||||
<linearGradient id="orangeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#E8590C"/>
|
||||
<stop offset="100%" stop-color="#FF8A4C"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- 背景虚线环 -->
|
||||
<circle cx="100" cy="100" r="85" class="ring-bg"/>
|
||||
<!-- 进度弧 -->
|
||||
<circle cx="100" cy="100" r="85" class="ring-progress"/>
|
||||
</svg>
|
||||
<div class="ring-center">
|
||||
<div>
|
||||
<span class="ring-score" data-field="score-after">87</span><span class="ring-max">/100</span>
|
||||
</div>
|
||||
<div class="ring-label">质量总分</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-text">
|
||||
<div class="hero-title">
|
||||
我的Skill进化报告<br>
|
||||
<span class="hero-skill-name" data-field="skill-name">审校降AI味</span>
|
||||
</div>
|
||||
<div class="hero-journey">
|
||||
从 <strong data-field="score-before">72</strong> 分进化到 <strong>87</strong> 分<br>
|
||||
<span style="color:#999;font-size:14px;" data-field="skill-id">huashu-proofreading</span>
|
||||
</div>
|
||||
<div class="delta-badge">
|
||||
<span data-field="score-delta">+15</span>
|
||||
<span class="delta-badge-label">分</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 最大突破区 -->
|
||||
<div class="breakthrough-section">
|
||||
<div class="breakthrough-card primary">
|
||||
<div class="breakthrough-label">最大突破</div>
|
||||
<div class="breakthrough-dim" data-field="top1-name">指令精度</div>
|
||||
<div class="breakthrough-score-row">
|
||||
<span class="breakthrough-from" data-field="top1-from">5</span>
|
||||
<span class="breakthrough-arrow">→</span>
|
||||
<span class="breakthrough-to" data-field="top1-to">9</span>
|
||||
</div>
|
||||
<div class="breakthrough-pct" data-field="top1-pct">+80%</div>
|
||||
<div class="breakthrough-story" data-field="top1-story">从模糊指令到精确可执行,指令精度翻了将近一倍</div>
|
||||
</div>
|
||||
<div class="breakthrough-card secondary">
|
||||
<div class="breakthrough-label">第二突破</div>
|
||||
<div class="breakthrough-dim" data-field="top2-name">工作流清晰度</div>
|
||||
<div class="breakthrough-score-row">
|
||||
<span class="breakthrough-from" data-field="top2-from">5</span>
|
||||
<span class="breakthrough-arrow">→</span>
|
||||
<span class="breakthrough-to" data-field="top2-to">8</span>
|
||||
</div>
|
||||
<div class="breakthrough-pct" data-field="top2-pct">+60%</div>
|
||||
<div class="breakthrough-story" data-field="top2-story">线性可执行步骤,每步都有明确检查点</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 全维度速览 -->
|
||||
<div class="dims-section">
|
||||
<div class="dims-header">八维度全景</div>
|
||||
<div class="dims-grid">
|
||||
<div class="dim-cell warm">
|
||||
<div class="dim-name">元数据</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-mid">+2</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">工作流</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">边界覆盖</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">4</span>
|
||||
<span class="dim-score">7</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">检查点</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">7</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-small">+1</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">指令精度</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">9</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+4</span>
|
||||
</div>
|
||||
<div class="dim-cell">
|
||||
<div class="dim-name">资源整合</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">7</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-small">+1</span>
|
||||
</div>
|
||||
<div class="dim-cell warm">
|
||||
<div class="dim-name">整体架构</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">6</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-mid">+2</span>
|
||||
</div>
|
||||
<div class="dim-cell hot">
|
||||
<div class="dim-name">实测表现</div>
|
||||
<div class="dim-score-row">
|
||||
<span class="dim-old-score">5</span>
|
||||
<span class="dim-score">8</span>
|
||||
</div>
|
||||
<span class="dim-arrow up-big">+3</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 改进摘要 -->
|
||||
<div class="summary-section">
|
||||
<div class="summary-header">关键改进</div>
|
||||
<div class="summary-items">
|
||||
<div class="summary-item" data-field="improve-1">补充异常处理fallback路径,边界覆盖从4飙升到7</div>
|
||||
<div class="summary-item" data-field="improve-2">工作流重组为线性可执行步骤,每步可验证</div>
|
||||
<div class="summary-item" data-field="improve-3">测试prompt覆盖率从60%提升到95%,实测表现大幅进化</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 底部品牌区 -->
|
||||
<div class="footer">
|
||||
<div class="footer-left">
|
||||
<div class="footer-brand">Darwin<span class="dot">.</span>skill</div>
|
||||
<div class="footer-slogan">像训练模型一样进化你的Skills</div>
|
||||
</div>
|
||||
<div class="footer-right">
|
||||
<div class="footer-url">github.com/alchaincyf/darwin-skill</div>
|
||||
<div class="footer-by">by 花叔</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 858 KiB |
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"scenario": "典型场景:单 skill 优化",
|
||||
"prompt": "用 darwin-skill 优化 huashu-xxx 这个 skill",
|
||||
"expected": "skill 应引导:Phase 0 检查 git/分支 → Phase 0.5 设计 2-3 个 test-prompts → Phase 1 spawn 独立 judge 评 9 维 rubric → 找最低维度(注意 dim2/3/4 相关簇)→ Phase 2 hill climbing(每轮 1 个维度,git ratchet)→ 检测触顶(连续 2 轮 Δ<2 自动 break)→ Phase 3 汇总 + 结果卡片"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"scenario": "典型场景:全量评估",
|
||||
"prompt": "评估所有 skills 的质量",
|
||||
"expected": "skill 应执行 Phase 0.5-1:扫描所有 SKILL.md → 跑 runtime 中立性 gate → 用 9 维 rubric 打基线分 → 输出评分卡片(按分数排序,标注短板维度),不进入 Phase 2 优化循环"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"scenario": "歧义/失败场景",
|
||||
"prompt": "我想让你帮我把这个 skill 改得更好一点",
|
||||
"expected": "skill 应识别为优化任务 → 询问优化范围(全量 / 单个)→ 检查异常(不在 git 仓库 / results.tsv 缺失等)按异常表 fallback → 设计测试 prompt 前展示给用户确认(检查点)"
|
||||
}
|
||||
]
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
name: git-guardrails-claude-code
|
||||
description: Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
|
||||
---
|
||||
|
||||
# Setup Git Guardrails
|
||||
|
||||
Sets up a PreToolUse hook that intercepts and blocks dangerous git commands before Claude executes them.
|
||||
|
||||
## What Gets Blocked
|
||||
|
||||
- `git push` (all variants including `--force`)
|
||||
- `git reset --hard`
|
||||
- `git clean -f` / `git clean -fd`
|
||||
- `git branch -D`
|
||||
- `git checkout .` / `git restore .`
|
||||
|
||||
When blocked, Claude sees a message telling it that it does not have authority to access these commands.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Ask scope
|
||||
|
||||
Ask the user: install for **this project only** (`.claude/settings.json`) or **all projects** (`~/.claude/settings.json`)?
|
||||
|
||||
### 2. Copy the hook script
|
||||
|
||||
The bundled script is at: [scripts/block-dangerous-git.sh](scripts/block-dangerous-git.sh)
|
||||
|
||||
Copy it to the target location based on scope:
|
||||
|
||||
- **Project**: `.claude/hooks/block-dangerous-git.sh`
|
||||
- **Global**: `~/.claude/hooks/block-dangerous-git.sh`
|
||||
|
||||
Make it executable with `chmod +x`.
|
||||
|
||||
### 3. Add hook to settings
|
||||
|
||||
Add to the appropriate settings file:
|
||||
|
||||
**Project** (`.claude/settings.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Global** (`~/.claude/settings.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.claude/hooks/block-dangerous-git.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the settings file already exists, merge the hook into existing `hooks.PreToolUse` array — don't overwrite other settings.
|
||||
|
||||
### 4. Ask about customization
|
||||
|
||||
Ask if user wants to add or remove any patterns from the blocked list. Edit the copied script accordingly.
|
||||
|
||||
### 5. Verify
|
||||
|
||||
Run a quick test:
|
||||
|
||||
```bash
|
||||
echo '{"tool_input":{"command":"git push origin main"}}' | <path-to-script>
|
||||
```
|
||||
|
||||
Should exit with code 2 and print a BLOCKED message to stderr.
|
||||
@@ -1,3 +0,0 @@
|
||||
interface:
|
||||
display_name: "Git Guardrails for Claude Code"
|
||||
short_description: "Block dangerous git commands"
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
INPUT=$(cat)
|
||||
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
|
||||
|
||||
DANGEROUS_PATTERNS=(
|
||||
"git push"
|
||||
"git reset --hard"
|
||||
"git clean -fd"
|
||||
"git clean -f"
|
||||
"git branch -D"
|
||||
"git checkout \."
|
||||
"git restore \."
|
||||
"push --force"
|
||||
"reset --hard"
|
||||
)
|
||||
|
||||
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
||||
if echo "$COMMAND" | grep -qE "$pattern"; then
|
||||
echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: grill-me
|
||||
description: A relentless interview to sharpen a plan or design.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Run a `/grilling` session.
|
||||
@@ -1,5 +0,0 @@
|
||||
interface:
|
||||
display_name: "Grill Me"
|
||||
short_description: "Sharpen a plan through interview"
|
||||
policy:
|
||||
allow_implicit_invocation: false
|
||||
Vendored
-15
@@ -1,15 +0,0 @@
|
||||
---
|
||||
name: implement
|
||||
description: "Implement a piece of work based on a spec or set of tickets."
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Implement the work described by the user in the spec or tickets.
|
||||
|
||||
Use /tdd where possible, at pre-agreed seams.
|
||||
|
||||
Run typechecking regularly, single test files regularly, and the full test suite once at the end.
|
||||
|
||||
Once done, use /code-review to review the work.
|
||||
|
||||
Commit your work to the current branch.
|
||||
@@ -1,5 +0,0 @@
|
||||
interface:
|
||||
display_name: "Implement"
|
||||
short_description: "Build work from a spec or tickets"
|
||||
policy:
|
||||
allow_implicit_invocation: false
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
---
|
||||
name: karpathy-guidelines
|
||||
description: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# Karpathy Guidelines
|
||||
|
||||
Behavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.
|
||||
|
||||
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
||||
|
||||
## 1. Think Before Coding
|
||||
|
||||
**Don't assume. Don't hide confusion. Surface tradeoffs.**
|
||||
|
||||
Before implementing:
|
||||
|
||||
- State your assumptions explicitly. If uncertain, ask.
|
||||
- If multiple interpretations exist, present them - don't pick silently.
|
||||
- If a simpler approach exists, say so. Push back when warranted.
|
||||
- If something is unclear, stop. Name what's confusing. Ask.
|
||||
|
||||
## 2. Simplicity First
|
||||
|
||||
**Minimum code that solves the problem. Nothing speculative.**
|
||||
|
||||
- No features beyond what was asked.
|
||||
- No abstractions for single-use code.
|
||||
- No "flexibility" or "configurability" that wasn't requested.
|
||||
- No error handling for impossible scenarios.
|
||||
|
||||
If you write 200 lines and it could be 50, rewrite it.
|
||||
|
||||
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
|
||||
|
||||
## 3. Surgical Changes
|
||||
|
||||
**Touch only what you must. Clean up only your own mess.**
|
||||
|
||||
When editing existing code:
|
||||
|
||||
- Don't "improve" adjacent code, comments, or formatting.
|
||||
- Don't refactor things that aren't broken.
|
||||
- Match existing style, even if you'd do it differently.
|
||||
- If you notice unrelated dead code, mention it - don't delete it.
|
||||
|
||||
When your changes create orphans:
|
||||
|
||||
- Remove imports/variables/functions that YOUR changes made unused.
|
||||
- Don't remove pre-existing dead code unless asked.
|
||||
|
||||
The test: Every changed line should trace directly to the user's request.
|
||||
|
||||
## 4. Goal-Driven Execution
|
||||
|
||||
**Define success criteria. Loop until verified.**
|
||||
|
||||
Transform tasks into verifiable goals:
|
||||
|
||||
- "Add validation" → "Write tests for invalid inputs, then make them pass"
|
||||
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
|
||||
- "Refactor X" → "Ensure tests pass before and after"
|
||||
|
||||
For multi-step tasks, state a brief plan:
|
||||
|
||||
```
|
||||
1. [Step] → verify: [check]
|
||||
2. [Step] → verify: [check]
|
||||
3. [Step] → verify: [check]
|
||||
```
|
||||
|
||||
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
|
||||
-262
@@ -1,262 +0,0 @@
|
||||
---
|
||||
name: pathfinding
|
||||
description: This skill should be used when requirements are unclear, brainstorming ideas, or when "pathfind", "brainstorm", "figure out", "clarify requirements", or "work through" are mentioned.
|
||||
metadata:
|
||||
version: "2.0.0"
|
||||
---
|
||||
|
||||
# Pathfinding
|
||||
|
||||
Adaptive Q&A → unclear requirements → clear path.
|
||||
|
||||
<when_to_use>
|
||||
|
||||
- Ambiguous/incomplete requirements
|
||||
- Complex features needing exploration
|
||||
- Greenfield projects with open questions
|
||||
- Collaborative brainstorming or problem solving
|
||||
|
||||
NOT for: time-critical bugs, well-defined tasks, obvious questions
|
||||
|
||||
</when_to_use>
|
||||
|
||||
<confidence>
|
||||
|
||||
| Bar | Lvl | % | Name | Action |
|
||||
|-----|-----|---|------|--------|
|
||||
| `░░░░░` | 0 | 0–19 | Prepping | Gather foundational context |
|
||||
| `▓░░░░` | 1 | 20–39 | Scouting | Ask broad questions |
|
||||
| `▓▓░░░` | 2 | 40–59 | Exploring | Ask focusing questions |
|
||||
| `▓▓▓░░` | 3 | 60–74 | Charting | Risky to proceed; gaps remain |
|
||||
| `▓▓▓▓░` | 4 | 75–89 | Mapped | Viable; push toward 5 |
|
||||
| `▓▓▓▓▓` | 5 | 90–100 | Ready | Deliver |
|
||||
|
||||
Start honest. Clear request → level 4–5. Vague → level 0–2.
|
||||
|
||||
At level 4: "Can proceed, but 1–2 more questions would reach full confidence. Continue or deliver now?"
|
||||
|
||||
Below level 5: include `△ Caveats` section.
|
||||
|
||||
</confidence>
|
||||
|
||||
<stages>
|
||||
|
||||
Load the **maintain-tasks** skill for stage tracking. Stages advance only, never regress.
|
||||
|
||||
| Stage | Trigger | activeForm |
|
||||
|-------|---------|------------|
|
||||
| Prep | level 0–1 | "Prepping" |
|
||||
| Explore | level 2–3 | "Exploring" |
|
||||
| Clarify | level 4 | "Clarifying" |
|
||||
| Deliver | level 5 | "Delivering" |
|
||||
|
||||
Task format — each stage gets context-specific title:
|
||||
|
||||
```text
|
||||
- Prep { domain } requirements
|
||||
- Explore { approach } options
|
||||
- Clarify { key unknowns, 3-4 words }
|
||||
- Deliver { artifact type }
|
||||
```
|
||||
|
||||
Situational (insert before Deliver when triggered):
|
||||
- Resolve Conflicts → `◆ Caution` or `◆◆ Hazard` pushback
|
||||
- Validate Assumptions → high-risk assumptions before delivery
|
||||
|
||||
Workflow:
|
||||
- Start: Create stage matching initial confidence `in_progress`
|
||||
- Transition: Mark current `completed`, add next `in_progress`
|
||||
- High start (4+): Skip directly to `Clarify` or `Deliver`
|
||||
- Early delivery: Skip to `Deliver` + `△ Caveats`
|
||||
|
||||
</stages>
|
||||
|
||||
<gather>
|
||||
|
||||
Calibrate first — user may have already provided context (docs, prior conversation, pointed you at files). If enough context exists, skip to level 3–4. Don't re-ask what's already clear.
|
||||
|
||||
If gaps remain, explore focus areas (pick what's relevant):
|
||||
- Purpose: What problem? Why now?
|
||||
- Constraints: Time, tech, team, dependencies
|
||||
- Success: How will we know it works?
|
||||
- Scope: What's in, what's out?
|
||||
|
||||
When multiple approaches exist:
|
||||
- Propose 2–3 options with trade-offs
|
||||
- Lead with recommendation ★ and reasoning
|
||||
- Let user pick, combine, or redirect
|
||||
|
||||
Principles:
|
||||
- YAGNI — cut what's not needed
|
||||
- DRY — don't duplicate effort or logic
|
||||
- Simplest thing — prefer boring solutions
|
||||
|
||||
</gather>
|
||||
|
||||
<questions>
|
||||
|
||||
Use `EnterPlanMode` for each question — enables keyboard navigation of options.
|
||||
|
||||
Structure:
|
||||
- Prose above tool: context, reasoning, ★ recommendation if clear lean
|
||||
- Inside tool: options only (concise, scannable)
|
||||
|
||||
At level 0 — start with session intent:
|
||||
- Quick pulse check vs deep dive?
|
||||
- Exploring possibilities or solving a specific problem?
|
||||
- What does "done" look like?
|
||||
|
||||
Levels 1–4 — focus on substance:
|
||||
- 2–4 options per question + "5. Something else"
|
||||
- Inline `[★]` on recommended option + *italicized rationale*
|
||||
- User replies: number, modifications, or combos
|
||||
|
||||
</questions>
|
||||
|
||||
<workflow>
|
||||
|
||||
Loop: Answer → Restate → Update Confidence → Next action
|
||||
|
||||
After each answer emit:
|
||||
- Confidence: {BAR} {NAME}
|
||||
- Assumptions: { if material }
|
||||
- Unknowns: { what we can clarify; note unknowables when relevant }
|
||||
- Decisions: { what's locked in }
|
||||
- Concerns: { what feels off + why }
|
||||
|
||||
Next action by level:
|
||||
- 0–2: Ask clarifying questions
|
||||
- 3: Summarize (3 bullets max), fork toward 5
|
||||
- 4: Offer choice: refine or proceed
|
||||
- 5: Deliver
|
||||
|
||||
</workflow>
|
||||
|
||||
<issues>
|
||||
|
||||
When answer reveals a concern mid-stream:
|
||||
- Pause before next question
|
||||
- Surface with `△` + brief description
|
||||
- Ask: clarify now, note for later, or proceed with assumption?
|
||||
|
||||
Example: "△ This assumes the API supports batch operations — clarify now, note for later, or proceed?"
|
||||
|
||||
If user proceeds despite significant gap → escalate to `pushback` protocol.
|
||||
|
||||
</issues>
|
||||
|
||||
<pushback>
|
||||
|
||||
Escalate when choice conflicts with goals/constraints/best practices:
|
||||
|
||||
- `◇ Alternative`: Minor misalignment. Present option + reasoning.
|
||||
- `◆ Caution`: Clear conflict. Recommend alternative, explain risks, ask to proceed. Triggers Resolve Conflicts.
|
||||
- `◆◆ Hazard`: High failure risk. Require mitigation or explicit override. Triggers Resolve Conflicts.
|
||||
|
||||
Override: Accept "Proceed anyway: {REASON}" → log in next reflection → mark Resolve Conflicts complete.
|
||||
|
||||
</pushback>
|
||||
|
||||
<skeptic>
|
||||
|
||||
Integrate skeptic agent for complexity sanity checks:
|
||||
|
||||
**Recommend** (offer choice):
|
||||
- Level 5 reached with △ Caveats > 2
|
||||
- Red flag language in decisions: "might need later", "more flexible", "best practice"
|
||||
|
||||
```text
|
||||
Before finalizing — you have {N} caveats. Want to run skeptic for a sanity check?
|
||||
[AskUserQuestion]
|
||||
1. Yes, quick check [★] — I'll challenge complexity interactively
|
||||
2. Yes, deep analysis — launch skeptic agent in background
|
||||
3. No, proceed — deliver as-is
|
||||
```
|
||||
|
||||
**Auto-invoke** (no choice):
|
||||
- Level 4+ with 3+ unknowns persisting across 2+ question cycles
|
||||
- ◆◆ Hazard escalation triggered during session
|
||||
|
||||
When auto-invoking:
|
||||
|
||||
```text
|
||||
[Auto-invoking skeptic — {REASON}]
|
||||
```
|
||||
|
||||
Launch with Task tool:
|
||||
- subagent_type: "outfitter:skeptic"
|
||||
- prompt: Include current decisions, unknowns, and caveats
|
||||
- run_in_background: false (wait for findings before delivery)
|
||||
|
||||
After skeptic returns:
|
||||
- Present findings to user
|
||||
- If verdict is `block` → add Resolve Conflicts stage
|
||||
- If verdict is `caution` → offer choice to address or acknowledge
|
||||
- If verdict is `proceed` → continue to delivery
|
||||
|
||||
</skeptic>
|
||||
|
||||
<completion>
|
||||
|
||||
Level 5: Produce artifact immediately (doc, plan, code, outline). If none specified, suggest one.
|
||||
|
||||
After delivering, ask where to persist (if applicable):
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. { discovered path } [★] — { source: `CLAUDE.md` preference | existing directory | convention }
|
||||
2. Create issue — { Linear/GitHub/Beads based on project context }
|
||||
3. ADR — { if architectural decision }
|
||||
4. Don't persist — keep in conversation only
|
||||
5. Something else — different location or format
|
||||
```
|
||||
|
||||
Discovery order for option 1:
|
||||
1. `CLAUDE.md` or project instructions with explicit plan storage preference
|
||||
2. Existing `.agents/plans/` directory
|
||||
3. Existing `docs/plans/` directory
|
||||
4. Fall back to `.agents/plans/` if nothing found
|
||||
|
||||
Always suggest filename based on topic. Match existing conventions if present.
|
||||
|
||||
Mark Deliver `completed` after artifact is delivered (persistence is optional follow-up).
|
||||
|
||||
Below 5: Append `△ Caveats`:
|
||||
- Open questions + context
|
||||
- Assumed decisions + defaults
|
||||
- Known concerns + impact
|
||||
- Deferred items + revisit timing
|
||||
|
||||
</completion>
|
||||
|
||||
<rules>
|
||||
|
||||
ALWAYS:
|
||||
- Task stage matching initial confidence at start
|
||||
- `EnterPlanMode` for each question (keyboard nav)
|
||||
- Prose above tool for context + ★ recommendation
|
||||
- One question at a time, wait for response
|
||||
- Restate + update confidence before next move
|
||||
- Update todos at level 4, level 5 thresholds
|
||||
- Apply pushback protocol on conflicts
|
||||
- Check skeptic triggers at level 4+ (unknowns, caveats, red flags)
|
||||
|
||||
NEVER:
|
||||
- Proceed from 0–3 without clarifying questions
|
||||
- Hide uncertainty below level 5
|
||||
- Stack questions or bury decisions in paragraphs
|
||||
- Put recommendation inside plan tool (keep in prose)
|
||||
- Skip reflection after answer
|
||||
- Regress stages
|
||||
- Ignore skeptic auto-invoke triggers
|
||||
|
||||
</rules>
|
||||
|
||||
<references>
|
||||
|
||||
- [confidence.md](references/confidence.md) — confidence deep dive
|
||||
- [questions.md](references/questions.md) — question crafting
|
||||
- [examples/](examples/) — session examples
|
||||
- skeptic agent (outfitter:skeptic) — complexity sanity checks
|
||||
|
||||
</references>
|
||||
@@ -1,344 +0,0 @@
|
||||
# Example: Early Delivery with Caveats
|
||||
|
||||
User requests delivery before reaching full confidence — demonstrates `△ Caveats` and mid-stream concerns.
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
I want to add real-time notifications to our app. Users should get notified when someone comments on their posts.
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
[Task] Getting oriented
|
||||
- Prep notification requirements (in_progress)
|
||||
- Explore delivery mechanisms (pending)
|
||||
- Clarify scale and persistence (pending)
|
||||
- Deliver implementation plan (pending)
|
||||
```
|
||||
|
||||
```text
|
||||
▓▓░░░ Exploring
|
||||
|
||||
Assumptions:
|
||||
- Existing app with posts and comments
|
||||
- User accounts with some form of auth
|
||||
- Web and/or mobile clients
|
||||
|
||||
Unknowns:
|
||||
- Current tech stack?
|
||||
- Scale (users, notifications/day)?
|
||||
- Notification types (just comments, or more)?
|
||||
- Persistence (history, read/unread)?
|
||||
- Push notifications (mobile) needed?
|
||||
|
||||
Decisions:
|
||||
- Real-time comment notifications
|
||||
```
|
||||
|
||||
**Q1**: What's your current tech stack?
|
||||
|
||||
*Why it matters — determines which real-time approach fits best*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Node.js backend — Socket.io, ws, or SSE
|
||||
2. Rust backend — Axum with WebSockets
|
||||
3. Serverless (Vercel, AWS Lambda) — needs external service (Pusher, Ably)
|
||||
4. Supabase — built-in realtime, minimal setup
|
||||
5. Something else — describe your stack
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
Node.js with Express, React frontend, PostgreSQL
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Classic PERN stack — lots of good options for real-time.
|
||||
|
||||
▓▓▓░░ Charting
|
||||
|
||||
Assumptions:
|
||||
- Can add WebSocket server alongside Express
|
||||
- React can handle WebSocket connections
|
||||
- PostgreSQL for notification storage
|
||||
|
||||
Unknowns:
|
||||
- Scale expectations?
|
||||
- Mobile app too, or web only?
|
||||
- Need notification history/persistence?
|
||||
|
||||
Decisions:
|
||||
- Node.js + Express + React + PostgreSQL
|
||||
- Real-time comment notifications
|
||||
|
||||
Concerns:
|
||||
- WebSocket scaling can get tricky with multiple server instances — may need Redis pub/sub or sticky sessions
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Shape emerging
|
||||
- Prep notification requirements (completed)
|
||||
- Explore delivery mechanisms (in_progress)
|
||||
- Clarify scale and persistence (pending)
|
||||
- Deliver implementation plan (pending)
|
||||
```
|
||||
|
||||
**Q2**: What scale are you expecting?
|
||||
|
||||
*Why it matters — affects architecture complexity significantly*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Small (< 1k users) [★] — single server, simple WebSockets *start here, scale later*
|
||||
2. Medium (1k-50k users) — needs Redis pub/sub for multi-server
|
||||
3. Large (50k+ users) — dedicated service (Pusher, Ably, or self-hosted)
|
||||
5. Something else — different constraints
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
We're small now but hoping to grow. Can we just get something working? I can come back for scaling later.
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Makes sense — ship something simple, optimize when needed.
|
||||
|
||||
▓▓▓░░ Charting
|
||||
|
||||
△ This assumes single-server deployment works for now — if you're already multi-instance, we'd need Redis pub/sub from the start. Clarify now, note for later, or proceed?
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
Single server for now, let's proceed
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Good — simple path forward.
|
||||
|
||||
▓▓▓▓░ Mapped
|
||||
|
||||
Assumptions:
|
||||
- Single server deployment
|
||||
- Web only (no mobile push for now)
|
||||
- Basic notification (no persistence/history initially)
|
||||
|
||||
Unknowns:
|
||||
- Want notification persistence (history, read/unread)?
|
||||
|
||||
Decisions:
|
||||
- Socket.io on Node.js (simplest for Express)
|
||||
- Single-server architecture
|
||||
- Real-time comment notifications
|
||||
|
||||
Concerns:
|
||||
- No persistence means notifications lost on refresh — might frustrate users
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Getting close
|
||||
- Prep notification requirements (completed)
|
||||
- Explore delivery mechanisms (completed)
|
||||
- Clarify scale and persistence (in_progress)
|
||||
- Deliver implementation plan (pending)
|
||||
```
|
||||
|
||||
**Q3**: Should notifications persist? (history, read/unread state)
|
||||
|
||||
*Why it matters — affects database schema and UX significantly*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. No persistence — real-time only, notifications disappear on refresh
|
||||
2. Basic persistence [★] — store in DB, show unread count *better UX, moderate effort*
|
||||
3. Full history — notification center, mark as read, pagination
|
||||
5. Something else — different approach
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
Actually, can you just give me what you have? I need to ship something today and can iterate.
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Understood — shipping now, iterating later.
|
||||
|
||||
▓▓▓░░ Charting → Deliver (early)
|
||||
|
||||
Skipping to delivery at level 3. Including caveats for what's unresolved.
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Early delivery — shipping with caveats
|
||||
- Prep notification requirements (completed)
|
||||
- Explore delivery mechanisms (completed)
|
||||
- Clarify scale and persistence (completed)
|
||||
- Deliver implementation plan (in_progress)
|
||||
```
|
||||
|
||||
## Real-Time Notifications — MVP Plan
|
||||
|
||||
**Architecture**:
|
||||
|
||||
```text
|
||||
┌─────────┐ WebSocket ┌─────────────┐
|
||||
│ React │◄──────────────────►│ Express │
|
||||
│ Client │ │ + Socket.io│
|
||||
└─────────┘ └──────┬──────┘
|
||||
│
|
||||
┌──────▼──────┐
|
||||
│ PostgreSQL │
|
||||
│ (comments) │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
**Server Setup** (add to existing Express app):
|
||||
|
||||
```typescript
|
||||
// server.ts
|
||||
import { Server } from 'socket.io';
|
||||
import { createServer } from 'http';
|
||||
|
||||
const httpServer = createServer(app);
|
||||
const io = new Server(httpServer, {
|
||||
cors: { origin: process.env.CLIENT_URL }
|
||||
});
|
||||
|
||||
// Track connected users
|
||||
const userSockets = new Map<string, string>(); // userId -> socketId
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
const userId = socket.handshake.auth.userId;
|
||||
userSockets.set(userId, socket.id);
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
userSockets.delete(userId);
|
||||
});
|
||||
});
|
||||
|
||||
// Export for use in routes
|
||||
export { io, userSockets };
|
||||
```
|
||||
|
||||
**Emit on Comment Creation**:
|
||||
|
||||
```typescript
|
||||
// routes/comments.ts
|
||||
import { io, userSockets } from '../server';
|
||||
|
||||
app.post('/posts/:postId/comments', async (req, res) => {
|
||||
const comment = await createComment(req.body);
|
||||
const post = await getPost(req.params.postId);
|
||||
|
||||
// Notify post author (if not self-comment)
|
||||
if (post.authorId !== req.user.id) {
|
||||
const socketId = userSockets.get(post.authorId);
|
||||
if (socketId) {
|
||||
io.to(socketId).emit('notification', {
|
||||
type: 'comment',
|
||||
postId: post.id,
|
||||
commentId: comment.id,
|
||||
fromUser: req.user.name,
|
||||
message: `${req.user.name} commented on your post`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
res.json(comment);
|
||||
});
|
||||
```
|
||||
|
||||
**React Client**:
|
||||
|
||||
```typescript
|
||||
// hooks/useNotifications.ts
|
||||
import { useEffect } from 'react';
|
||||
import { io } from 'socket.io-client';
|
||||
import { toast } from 'your-toast-library';
|
||||
|
||||
export function useNotifications(userId: string) {
|
||||
useEffect(() => {
|
||||
const socket = io(process.env.REACT_APP_API_URL, {
|
||||
auth: { userId }
|
||||
});
|
||||
|
||||
socket.on('notification', (data) => {
|
||||
toast(data.message);
|
||||
// Could also update a notification count in state
|
||||
});
|
||||
|
||||
return () => { socket.disconnect(); };
|
||||
}, [userId]);
|
||||
}
|
||||
```
|
||||
|
||||
**Next Steps**:
|
||||
|
||||
1. `npm install socket.io` (server) and `socket.io-client` (client)
|
||||
2. Add Socket.io to your Express server
|
||||
3. Wire up comment creation to emit notifications
|
||||
4. Add `useNotifications` hook to your app root
|
||||
|
||||
---
|
||||
|
||||
## △ Caveats
|
||||
|
||||
**Open questions**:
|
||||
- Notification persistence — currently lost on refresh
|
||||
- Mobile push — not addressed, would need separate implementation
|
||||
|
||||
**Assumed decisions**:
|
||||
- Single server deployment — will break with multiple instances
|
||||
- No read/unread tracking — no notification history
|
||||
- Toast-only UI — no notification center
|
||||
|
||||
**Known concerns**:
|
||||
- User might miss notifications if offline when sent
|
||||
- No retry mechanism for failed deliveries
|
||||
- Socket reconnection handling is minimal
|
||||
|
||||
**Deferred items**:
|
||||
- Redis pub/sub for multi-server (when you scale)
|
||||
- Notification persistence in PostgreSQL (soon — improves UX)
|
||||
- Mobile push notifications (when you add mobile app)
|
||||
- Notification preferences (mute, frequency)
|
||||
|
||||
```text
|
||||
[Task] Done — shipped with caveats
|
||||
- Prep notification requirements (completed)
|
||||
- Explore delivery mechanisms (completed)
|
||||
- Clarify scale and persistence (completed)
|
||||
- Deliver implementation plan (completed)
|
||||
```
|
||||
|
||||
Shipped — MVP real-time notifications ready to go. Come back when you need persistence or scaling.
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
@@ -1,342 +0,0 @@
|
||||
# Example: Greenfield API Design
|
||||
|
||||
Starting from zero — vague request, no context.
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
I need to build an API
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
[Task] Getting oriented
|
||||
- Prep API requirements (in_progress)
|
||||
- Explore architecture options (pending)
|
||||
- Clarify data and auth needs (pending)
|
||||
- Deliver API design doc (pending)
|
||||
```
|
||||
|
||||
```text
|
||||
░░░░░ Prepping
|
||||
|
||||
Unknowns:
|
||||
- What domain/purpose?
|
||||
- Who consumes it?
|
||||
- What data?
|
||||
- Performance/scale needs?
|
||||
- Existing infrastructure?
|
||||
```
|
||||
|
||||
**Q1**: Before we dive in — what kind of session are you looking for?
|
||||
|
||||
*Why it matters — sets the right depth and pace*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Quick pulse check [★] — nail down key decisions, move fast *good for exploring direction*
|
||||
2. Deep dive — thorough exploration, comprehensive plan
|
||||
3. Specific problem — I know what I want, need help with one aspect
|
||||
5. Something else — describe what you're after
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
1, I have a rough idea but need to figure out the shape
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Got it — quick pulse to find the shape, then we can go deeper where needed.
|
||||
|
||||
▓░░░░ Scouting
|
||||
|
||||
Decisions:
|
||||
- Quick pulse session, fast iteration
|
||||
```
|
||||
|
||||
**Q2**: What's this API for?
|
||||
|
||||
*Why it matters — determines data model, auth strategy, and scaling approach*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Internal tool — dashboard, admin, ops
|
||||
2. Public product API — third-party developers
|
||||
3. Mobile/web backend — your own apps
|
||||
4. B2B integration — partner systems
|
||||
5. Something else — describe the use case
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
3, it's for a fitness tracking app
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Fitness tracking backend — workouts, metrics, user data. Classic mobile backend pattern.
|
||||
|
||||
▓▓░░░ Exploring
|
||||
|
||||
Assumptions:
|
||||
- User accounts with personal data
|
||||
- Workout/activity logging
|
||||
- Progress tracking over time
|
||||
- Mobile-first (iOS/Android)
|
||||
|
||||
Unknowns:
|
||||
- Social features? (friends, sharing, leaderboards)
|
||||
- Device integrations? (Apple Health, Fitbit, etc.)
|
||||
- Real-time needs? (live workouts, streaming)
|
||||
- Offline sync requirements?
|
||||
|
||||
Decisions:
|
||||
- Mobile/web backend for fitness app
|
||||
- Quick pulse session
|
||||
```
|
||||
|
||||
**Q3**: What's the core loop users will do most often?
|
||||
|
||||
*Why it matters — shapes the data model and API surface*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Log workouts manually [★] — exercises, sets, reps, weights *simplest starting point*
|
||||
2. Track metrics — weight, body measurements, progress photos
|
||||
3. Follow programs — structured plans, scheduled workouts
|
||||
4. Social/compete — friends, challenges, leaderboards
|
||||
5. Something else — different core interaction
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
1 and 2, logging workouts and tracking body metrics
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Core loop: log workouts + track body metrics. Good foundation — can layer social/programs later.
|
||||
|
||||
▓▓▓░░ Charting
|
||||
|
||||
Assumptions:
|
||||
- User model with profile data
|
||||
- Workout sessions with exercises
|
||||
- Body metrics (weight, measurements) with timestamps
|
||||
- Historical data for progress charts
|
||||
|
||||
Unknowns:
|
||||
- Auth approach?
|
||||
- Exercise library (predefined vs custom)?
|
||||
- Offline-first or always-online?
|
||||
|
||||
Decisions:
|
||||
- Mobile backend for fitness app
|
||||
- Core: workout logging + body metrics
|
||||
- Start simple, extensible for social/programs later
|
||||
|
||||
Concerns:
|
||||
- Exercise data can get complex (variations, equipment, muscle groups) — start with simple model, don't over-engineer
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Shape emerging — exploring options
|
||||
- Prep API requirements (completed)
|
||||
- Explore architecture options (in_progress)
|
||||
- Clarify data and auth needs (pending)
|
||||
- Deliver API design doc (pending)
|
||||
```
|
||||
|
||||
**Q4**: How should users authenticate?
|
||||
|
||||
*Why it matters — affects security model, user experience, and implementation complexity*
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Email/password [★] — simple, universal *good starting point*
|
||||
2. Social login (Google/Apple) — better UX, less friction
|
||||
3. Both — maximum flexibility
|
||||
4. Magic link — passwordless, email-based
|
||||
5. Something else — different auth approach
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
3, I want both options
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Both email/password and social login — covers all users.
|
||||
|
||||
▓▓▓▓░ Mapped
|
||||
|
||||
Assumptions:
|
||||
- JWT tokens for mobile auth
|
||||
- Email as primary identifier (link accounts by email)
|
||||
- Refresh token rotation for security
|
||||
|
||||
Unknowns:
|
||||
- Specific social providers (Google, Apple, both)?
|
||||
|
||||
Decisions:
|
||||
- Dual auth: email/password + social login
|
||||
- Workout logging + body metrics core
|
||||
- Mobile backend architecture
|
||||
|
||||
Concerns:
|
||||
- Account linking edge cases (same email, different providers) — handle gracefully
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Getting close — one more detail
|
||||
- Prep API requirements (completed)
|
||||
- Explore architecture options (completed)
|
||||
- Clarify data and auth needs (in_progress)
|
||||
- Deliver API design doc (pending)
|
||||
```
|
||||
|
||||
Can proceed now, or one more question would nail down the social providers. Your call — deliver now or refine?
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
Let's just do Google and Apple for now
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
Google + Apple — covers iOS and Android users well.
|
||||
|
||||
▓▓▓▓▓ Ready
|
||||
|
||||
Decisions:
|
||||
- Dual auth: email/password + Google + Apple Sign-In
|
||||
- Core features: workout logging, body metrics tracking
|
||||
- JWT tokens with refresh rotation
|
||||
- Mobile-first REST API
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Clear path — delivering design
|
||||
- Prep API requirements (completed)
|
||||
- Explore architecture options (completed)
|
||||
- Clarify data and auth needs (completed)
|
||||
- Deliver API design doc (in_progress)
|
||||
```
|
||||
|
||||
## Fitness Tracking API Design
|
||||
|
||||
**Core Resources**:
|
||||
|
||||
```text
|
||||
/auth
|
||||
POST /register — email/password signup
|
||||
POST /login — email/password login
|
||||
POST /oauth/google — Google Sign-In
|
||||
POST /oauth/apple — Apple Sign-In
|
||||
POST /refresh — refresh access token
|
||||
POST /logout — invalidate tokens
|
||||
|
||||
/users
|
||||
GET /me — current user profile
|
||||
PUT /me — update profile
|
||||
DELETE /me — delete account
|
||||
|
||||
/workouts
|
||||
GET / — list workouts (paginated)
|
||||
POST / — create workout
|
||||
GET /:id — get workout details
|
||||
PUT /:id — update workout
|
||||
DELETE /:id — delete workout
|
||||
|
||||
/exercises
|
||||
GET / — list exercises (library)
|
||||
POST / — create custom exercise
|
||||
|
||||
/metrics
|
||||
GET / — list body metrics (paginated)
|
||||
POST / — log new metric
|
||||
GET /summary — progress summary (charts data)
|
||||
```
|
||||
|
||||
**Data Models**:
|
||||
|
||||
```text
|
||||
User {
|
||||
id, email, name, avatar_url,
|
||||
auth_provider: "email" | "google" | "apple",
|
||||
created_at, updated_at
|
||||
}
|
||||
|
||||
Workout {
|
||||
id, user_id, name, started_at, ended_at,
|
||||
exercises: [{ exercise_id, sets: [{ reps, weight, duration }] }],
|
||||
notes, created_at
|
||||
}
|
||||
|
||||
Exercise {
|
||||
id, name, category, muscle_groups[],
|
||||
is_custom, user_id (if custom)
|
||||
}
|
||||
|
||||
BodyMetric {
|
||||
id, user_id, type: "weight" | "measurement",
|
||||
value, unit, measured_at
|
||||
}
|
||||
```
|
||||
|
||||
**Tech Stack Suggestion**:
|
||||
|
||||
- **API**: Hono or Express on Bun
|
||||
- **Database**: PostgreSQL (Supabase or Neon)
|
||||
- **Auth**: Custom JWT or Supabase Auth
|
||||
- **Hosting**: Railway, Fly.io, or Vercel
|
||||
|
||||
**Next Steps**:
|
||||
|
||||
1. Set up project with Bun + Hono
|
||||
2. Configure PostgreSQL with migrations
|
||||
3. Implement auth endpoints first
|
||||
4. Build workout CRUD
|
||||
5. Add body metrics
|
||||
6. Deploy MVP
|
||||
|
||||
```text
|
||||
[Task] Done — design shipped
|
||||
- Prep API requirements (completed)
|
||||
- Explore architecture options (completed)
|
||||
- Clarify data and auth needs (completed)
|
||||
- Deliver API design doc (completed)
|
||||
```
|
||||
|
||||
All set — went from "I need an API" to a concrete design. Ready to start building when you are.
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
@@ -1,242 +0,0 @@
|
||||
# Example: High Start (Level 4)
|
||||
|
||||
Clear request with context — minimal clarification needed, fast to delivery.
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
I need to add a dark mode toggle to my Next.js app. I'm using Tailwind CSS and want to persist the preference in localStorage. Should work with system preference as a default.
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
[Task] Clear requirements — fast path
|
||||
- Clarify implementation details (in_progress)
|
||||
- Deliver dark mode implementation (pending)
|
||||
```
|
||||
|
||||
```text
|
||||
▓▓▓▓░ Mapped
|
||||
|
||||
You've given me most of what I need:
|
||||
- Next.js + Tailwind CSS
|
||||
- Toggle component
|
||||
- localStorage persistence
|
||||
- System preference default
|
||||
|
||||
Assumptions:
|
||||
- Tailwind's built-in dark mode (class strategy)
|
||||
- Client-side toggle (no server preference)
|
||||
- Standard light/dark, no custom themes
|
||||
|
||||
Decisions:
|
||||
- Dark mode with localStorage + system fallback
|
||||
- Tailwind class strategy
|
||||
- Toggle UI component
|
||||
```
|
||||
|
||||
Can deliver now, or one quick question: where does the toggle live? (header, settings page, floating button)
|
||||
|
||||
[★] If you just want the implementation and will place it yourself, I can skip that question.
|
||||
|
||||
```text
|
||||
[EnterPlanMode]
|
||||
1. Skip — just give me the implementation
|
||||
2. Header/navbar — always visible
|
||||
3. Settings page — dedicated settings area
|
||||
4. Floating button — corner of screen
|
||||
5. Something else — different placement
|
||||
```
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
|
||||
<turn>
|
||||
<user>
|
||||
|
||||
1, I'll put it in my header
|
||||
|
||||
</user>
|
||||
<claude>
|
||||
|
||||
```text
|
||||
▓▓▓▓▓ Ready
|
||||
|
||||
All clear — delivering implementation.
|
||||
```
|
||||
|
||||
```text
|
||||
[Task] Delivering
|
||||
- Clarify implementation details (completed)
|
||||
- Deliver dark mode implementation (in_progress)
|
||||
```
|
||||
|
||||
## Dark Mode Implementation
|
||||
|
||||
**1. Configure Tailwind** (`tailwind.config.js`):
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
darkMode: 'class',
|
||||
// ... rest of config
|
||||
}
|
||||
```
|
||||
|
||||
**2. Theme Provider** (`components/theme-provider.tsx`):
|
||||
|
||||
```typescript
|
||||
'use client';
|
||||
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
|
||||
type Theme = 'light' | 'dark' | 'system';
|
||||
|
||||
const ThemeContext = createContext<{
|
||||
theme: Theme;
|
||||
setTheme: (theme: Theme) => void;
|
||||
}>({ theme: 'system', setTheme: () => {} });
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [theme, setTheme] = useState<Theme>('system');
|
||||
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem('theme') as Theme | null;
|
||||
if (stored) setTheme(stored);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
root.classList.remove('light', 'dark');
|
||||
|
||||
if (theme === 'system') {
|
||||
root.classList.add(systemDark ? 'dark' : 'light');
|
||||
} else {
|
||||
root.classList.add(theme);
|
||||
}
|
||||
|
||||
localStorage.setItem('theme', theme);
|
||||
}, [theme]);
|
||||
|
||||
// Listen for system preference changes
|
||||
useEffect(() => {
|
||||
const media = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const handler = () => {
|
||||
if (theme === 'system') {
|
||||
document.documentElement.classList.remove('light', 'dark');
|
||||
document.documentElement.classList.add(media.matches ? 'dark' : 'light');
|
||||
}
|
||||
};
|
||||
media.addEventListener('change', handler);
|
||||
return () => media.removeEventListener('change', handler);
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, setTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const useTheme = () => useContext(ThemeContext);
|
||||
```
|
||||
|
||||
**3. Toggle Component** (`components/theme-toggle.tsx`):
|
||||
|
||||
```typescript
|
||||
'use client';
|
||||
|
||||
import { useTheme } from './theme-provider';
|
||||
import { Sun, Moon, Monitor } from 'lucide-react'; // or your icon library
|
||||
|
||||
export function ThemeToggle() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
|
||||
const cycle = () => {
|
||||
const next = theme === 'light' ? 'dark' : theme === 'dark' ? 'system' : 'light';
|
||||
setTheme(next);
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={cycle}
|
||||
className="p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-800"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
{theme === 'light' && <Sun className="w-5 h-5" />}
|
||||
{theme === 'dark' && <Moon className="w-5 h-5" />}
|
||||
{theme === 'system' && <Monitor className="w-5 h-5" />}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**4. Wrap App** (`app/layout.tsx`):
|
||||
|
||||
```typescript
|
||||
import { ThemeProvider } from '@/components/theme-provider';
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body>
|
||||
<ThemeProvider>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**5. Prevent Flash** (add to `<head>` in layout):
|
||||
|
||||
```typescript
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme') || 'system';
|
||||
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const isDark = theme === 'dark' || (theme === 'system' && systemDark);
|
||||
document.documentElement.classList.add(isDark ? 'dark' : 'light');
|
||||
})();
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
**6. Use in Header**:
|
||||
|
||||
```typescript
|
||||
import { ThemeToggle } from '@/components/theme-toggle';
|
||||
|
||||
export function Header() {
|
||||
return (
|
||||
<header className="flex items-center justify-between p-4">
|
||||
<Logo />
|
||||
<nav>{/* ... */}</nav>
|
||||
<ThemeToggle />
|
||||
</header>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Usage**:
|
||||
- Click toggle: cycles light → dark → system → light
|
||||
- System mode: follows OS preference automatically
|
||||
- Persists in localStorage across sessions
|
||||
- No flash on page load
|
||||
|
||||
```text
|
||||
[Task] Done
|
||||
- Clarify implementation details (completed)
|
||||
- Deliver dark mode implementation (completed)
|
||||
```
|
||||
|
||||
All set — drop `<ThemeToggle />` in your header and you're good.
|
||||
|
||||
</claude>
|
||||
</turn>
|
||||
@@ -1,146 +0,0 @@
|
||||
# Confidence
|
||||
|
||||
Confidence reflects certainty that you can deliver the requested outcome with the available information.
|
||||
|
||||
## Philosophy
|
||||
|
||||
Balance two goals:
|
||||
1. **Gather enough** to deliver quality results
|
||||
2. **Avoid over-questioning** that frustrates user
|
||||
|
||||
Consider:
|
||||
- **Clarity**: How well-defined is the ask?
|
||||
- **Risk**: What happens if assumptions are wrong?
|
||||
- **Complexity**: How many moving parts?
|
||||
- **Ambiguity**: How many valid interpretations?
|
||||
|
||||
## Level Overview
|
||||
|
||||
| Bar | Level | Name | Internal % |
|
||||
| --------- | ----- | ------------ | ---------- |
|
||||
| `░░░░░` | 0 | **Prepping** | 0–19% |
|
||||
| `▓░░░░` | 1 | **Scouting** | 20–39% |
|
||||
| `▓▓░░░` | 2 | **Exploring**| 40–59% |
|
||||
| `▓▓▓░░` | 3 | **Charting** | 60–74% |
|
||||
| `▓▓▓▓░` | 4 | **Mapped** | 75–89% |
|
||||
| `▓▓▓▓▓` | 5 | **Ready** | 90–100% |
|
||||
|
||||
## Stage Transitions
|
||||
|
||||
Confidence levels trigger stage transitions. Stages always advance, never regress.
|
||||
|
||||
### Stage-Confidence Mapping
|
||||
|
||||
| Level | Stage | activeForm |
|
||||
|-------|-------|------------|
|
||||
| 0–1 | Prep | "Prepping" |
|
||||
| 2–3 | Explore | "Exploring" |
|
||||
| 4 | Clarify | "Clarifying" |
|
||||
| 5 | Deliver | "Delivering" |
|
||||
|
||||
### Rules
|
||||
|
||||
1. **No regression**: If confidence drops (4 → 3), stay in current stage
|
||||
2. **Skip when starting high**: Level 5 start → go directly to Deliver
|
||||
3. **Stage independence**: Confidence can fluctuate within a stage
|
||||
4. **Early delivery**: User can request delivery at any stage → add `△ Caveats`
|
||||
|
||||
### Edge Cases
|
||||
|
||||
**High start**: Clear requirements → Start at Ready, go directly to Deliver
|
||||
|
||||
**Confidence drop**: Reach Mapped (4), enter Clarify, then realize gap (drops to 3) → Stay in Clarify, ask targeted questions
|
||||
|
||||
**Rapid ascent**: Start at Exploring (2) → one answer jumps to Mapped (4) → next to Ready (5) → transition through stages quickly
|
||||
|
||||
### Level 0: Prepping `░░░░░`
|
||||
|
||||
**Stage**: Prep
|
||||
|
||||
**When**: Request completely unclear, no domain context, pure guessing
|
||||
|
||||
**Ask**: Scope, constraints, goals, background
|
||||
|
||||
**Example**: "Make it better" with no context about what "it" is.
|
||||
|
||||
### Level 1: Scouting `▓░░░░`
|
||||
|
||||
**Stage**: Prep
|
||||
|
||||
**When**: Vague direction, domain clear but specifics aren't
|
||||
|
||||
**Ask**: What system? How big? What's in place?
|
||||
|
||||
**Example**: "Improvements to the dashboard" — which kind?
|
||||
|
||||
### Level 2: Exploring `▓▓░░░`
|
||||
|
||||
**Stage**: Explore
|
||||
|
||||
**When**: General area understood, lack critical details, multiple approaches possible
|
||||
|
||||
**Ask**: Which approach? What about X? What matters most? Speed vs quality?
|
||||
|
||||
**Example**: "Authentication" — method, scale, existing system unknown.
|
||||
|
||||
### Level 3: Charting `▓▓▓░░`
|
||||
|
||||
**Stage**: Explore
|
||||
|
||||
**When**: Reasonable understanding, could deliver with notable assumptions
|
||||
|
||||
**Do**:
|
||||
1. Summarize (3 bullets max)
|
||||
2. Ask 2–3 targeted questions toward level 4–5
|
||||
3. If user proceeds early → add `△ Caveats`
|
||||
|
||||
**Example**: OAuth login — general approach known, need providers + fallback strategy.
|
||||
|
||||
### Level 4: Mapped `▓▓▓▓░`
|
||||
|
||||
**Stage**: Clarify
|
||||
|
||||
**When**: Solid understanding, few clarifications would reach Ready, low risk
|
||||
|
||||
**Do**: Offer choice — "Can proceed, but 1–2 more questions would reach full confidence. Continue or deliver now?"
|
||||
|
||||
**Example**: New API endpoint — data model understood, need error handling approach.
|
||||
|
||||
### Level 5: Ready `▓▓▓▓▓`
|
||||
|
||||
**Stage**: Deliver
|
||||
|
||||
**When**: Clear understanding, no major assumptions, minimal risk
|
||||
|
||||
**Do**: Produce artifact immediately, succinct next steps, no more questions unless something emerges
|
||||
|
||||
**Example**: "Add logout button to header" — clear, specific, low-risk.
|
||||
|
||||
## Special Cases
|
||||
|
||||
### Starting Confidence
|
||||
|
||||
Start honest. Don't artificially start low if the request is clear.
|
||||
|
||||
- **Clear request** → level 4–5
|
||||
- **Vague request** → level 0–2
|
||||
|
||||
### Delivering Below Level 5
|
||||
|
||||
User wants quick delivery at lower confidence:
|
||||
|
||||
1. Confirm they want to proceed
|
||||
2. Add `△ Caveats` section
|
||||
3. List assumptions, concerns, unknowns
|
||||
|
||||
### Calibration
|
||||
|
||||
- Deliver at 5, goes well → calibrated
|
||||
- Deliver at 5, miss the mark → overconfident
|
||||
- Stay at 0–2 too long → underconfident
|
||||
|
||||
## Tuning
|
||||
|
||||
Percentage boundaries can adjust based on risk tolerance:
|
||||
- **Higher risk tolerance** → shift boundaries down
|
||||
- **Lower risk tolerance** → shift boundaries up
|
||||
@@ -1,132 +0,0 @@
|
||||
# Question Format
|
||||
|
||||
## Anatomy of a Good Question
|
||||
|
||||
**Components**:
|
||||
1. **Q{N}**: Question number (for tracking)
|
||||
2. **Question**: Clear, specific, focused on one decision
|
||||
3. **Why it matters**: One sentence explaining impact
|
||||
4. **Options**: 2–4 meaningful choices
|
||||
5. **Nuance**: Brief context for each option
|
||||
6. **★ Recommendation** (optional): Your lean with reasoning
|
||||
|
||||
## Delivery via EnterPlanMode
|
||||
|
||||
Use `EnterPlanMode` for each question — enables keyboard navigation.
|
||||
|
||||
**Structure**:
|
||||
- **Prose above tool**: context, reasoning, ★ recommendation
|
||||
- **Inside tool**: options only (concise, scannable)
|
||||
|
||||
Don't bury recommendations inside the tool — keep them visible in prose.
|
||||
|
||||
## Crafting Options
|
||||
|
||||
### Option Count Guidelines
|
||||
|
||||
**2 options**: Use when choices are binary or you want to keep it simple
|
||||
- Good: "Web app or mobile app?"
|
||||
- Avoid: Forcing false dichotomy when more options exist
|
||||
|
||||
**3 options**: Sweet spot for most questions
|
||||
- Good: Covers main approaches plus one alternative
|
||||
- Avoid: Making options too similar
|
||||
|
||||
**4 options**: Use when you need a combination or "other"
|
||||
- Good: Three distinct approaches + a hybrid option
|
||||
- Avoid: Analysis paralysis with too many choices
|
||||
|
||||
### Option Quality
|
||||
|
||||
**Good options**:
|
||||
- Mutually exclusive (can pick only one)
|
||||
- Collectively exhaustive (covers reasonable space)
|
||||
- Clearly differentiated (not subtle variations)
|
||||
- Actionable (leads to concrete next steps)
|
||||
|
||||
**Bad options**:
|
||||
- Overlapping: "Option 1: Use React. Option 2: Use modern framework."
|
||||
- Too similar: "Option 1: 100ms timeout. Option 2: 150ms timeout."
|
||||
- Vague: "Option 1: Do it the normal way."
|
||||
- Open-ended: "Option 1: Whatever you think is best."
|
||||
|
||||
## Why It Matters
|
||||
|
||||
The one-sentence explanation serves multiple purposes:
|
||||
1. **Context**: Helps user understand why you're asking
|
||||
2. **Priority**: Shows this isn't arbitrary
|
||||
3. **Decision framing**: Clarifies what depends on this choice
|
||||
4. **Respect**: Demonstrates you're not just asking for the sake of asking
|
||||
|
||||
**Good examples**:
|
||||
- "Why it matters — determines database schema design"
|
||||
- "Why it matters — affects performance characteristics and scaling strategy"
|
||||
- "Why it matters — impacts user experience for first-time visitors"
|
||||
|
||||
**Weak examples**:
|
||||
- "Why it matters — I need to know"
|
||||
- "Why it matters — this is important"
|
||||
- "Why it matters — because"
|
||||
|
||||
## Adding Nuance
|
||||
|
||||
Each option should include helpful context:
|
||||
|
||||
**Good nuance**:
|
||||
- Trade-offs: "Faster to implement but less flexible long-term"
|
||||
- Implications: "Requires HTTPS and external dependency"
|
||||
- Prerequisites: "Need existing user database"
|
||||
- Typical use case: "Best for high-traffic applications"
|
||||
|
||||
**Weak nuance**:
|
||||
- Restating the obvious: "Uses OAuth" (when option says OAuth)
|
||||
- Generic statements: "Good option"
|
||||
- No information: Just the option name with no context
|
||||
|
||||
## Recommendations (★)
|
||||
|
||||
Use recommendations when:
|
||||
- You have genuine expertise or insight
|
||||
- One option clearly fits better for typical cases
|
||||
- User seems uncertain or asks for guidance
|
||||
|
||||
**Don't recommend when**:
|
||||
- Purely user preference (e.g., color scheme)
|
||||
- Not enough context yet
|
||||
- All options equally valid
|
||||
|
||||
**Good**: `1. React [★] — mature ecosystem *best starting point for most teams*`
|
||||
|
||||
**Weak**:
|
||||
- ★ I like this one
|
||||
- ★ Most popular
|
||||
- Recommendation buried in prose above options
|
||||
|
||||
## User Replies
|
||||
|
||||
Number is a shorthand, not a constraint:
|
||||
- `2` → selects option 2
|
||||
- `2, but with caching` → selection + modification
|
||||
- `2 and 3` → combo
|
||||
- `What's the difference?` → clarification request
|
||||
|
||||
All valid.
|
||||
|
||||
## Adaptive Cadence
|
||||
|
||||
**Baseline** (~80% of questions):
|
||||
- Clear question + one-sentence "why"
|
||||
- 2–4 options with brief nuance
|
||||
- Inline `[★]` on recommended option
|
||||
- Optional: `[★] { expanded reasoning }` in prose above if helpful
|
||||
|
||||
**Expand when**:
|
||||
- High ambiguity or risk
|
||||
- User uncertain or asks for detail
|
||||
- Technical complexity needs explanation
|
||||
|
||||
**Simplify when**:
|
||||
- Straightforward question
|
||||
- User shows expertise
|
||||
- Question 6+ in session
|
||||
- User wants to move faster
|
||||
Vendored
-67
@@ -1,67 +0,0 @@
|
||||
# Logic Prototype
|
||||
|
||||
A single, self-contained HTML file — a **shareable demo** — that lets anyone drive a state model by clicking buttons. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
||||
|
||||
Because it's one file with nothing to install, you can hand it to a non-developer — a designer, a PM, a domain expert — and let them feel the model for themselves. So it speaks their language, not the code's.
|
||||
|
||||
## When this is the right shape
|
||||
|
||||
- "I'm not sure if this state machine handles the edge case where X then Y."
|
||||
- "Does this data model actually let me represent the case where..."
|
||||
- "I want to feel out what the API should look like before writing it."
|
||||
- Anything where someone wants to **press buttons and watch state change**.
|
||||
|
||||
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
|
||||
|
||||
## Process
|
||||
|
||||
### 1. State the question
|
||||
|
||||
Before writing code, write down what state model and what question you're prototyping. One paragraph, at the top of the demo (in a visible intro, not just a comment). A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
|
||||
|
||||
### 2. Isolate the logic in a portable module
|
||||
|
||||
Put the actual logic — the bit that's answering the question — in a single `<script>` block written as a small, pure module that could be lifted out and dropped into the real codebase later. The page around it is throwaway; this module isn't.
|
||||
|
||||
The right shape depends on the question:
|
||||
|
||||
- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
|
||||
- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
|
||||
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
|
||||
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
||||
|
||||
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a page. Keep it pure: no DOM, no `document`, no button handlers reaching inside it. The page calls into it; nothing flows the other direction. This is what makes the prototype useful past its own lifetime: once the question's answered, the validated reducer / machine / function set lifts into the real module on its own.
|
||||
|
||||
### 3. Build the shareable HTML file
|
||||
|
||||
One file, plain HTML/CSS/JS — no framework, no bundler, no server, everything inline so it opens by double-click and survives being emailed around. Anyone should be able to run it by opening it.
|
||||
|
||||
Write it for a non-developer. Every label is in **domain language**, not code — buttons and state read like the business, not the reducer. Explain in plain words what's happening.
|
||||
|
||||
Lay it out with a clean hierarchy, top to bottom:
|
||||
|
||||
1. **Title and one-line explanation** of what this demo lets you explore (the question from step 1).
|
||||
2. **Current state** — the full relevant state, rendered as a readable panel (labelled fields, not a raw JSON dump), re-rendered after every click so the change is visible. Where it helps a non-developer follow, call out what just changed.
|
||||
3. **Free-play buttons** — one button per action, always available, so anyone can poke at the model in any order. Each click dispatches its action and re-renders the state.
|
||||
4. **Guided walkthroughs** — a set of **scenarios**, one per tab. Each tab holds a short plain-language description of the scenario — the situation it sets up and what to watch for — and underneath it, the ordered **buttons to press** for that scenario. Each step is a real button: clicking it performs that action and moves to the next step. Starting a walkthrough resets to a known initial state so the scenario runs the same way every time.
|
||||
|
||||
Choose scenarios that demonstrate the awkward cases — the happy path, a tricky edge case, an attempt at something that should be illegal — the ones hard to reason about on paper.
|
||||
|
||||
Keep it beautiful but restrained: clean typography, generous spacing, one accent colour. No animations, no gimmicks — nothing that competes with the state and the buttons.
|
||||
|
||||
### 4. Hand it over
|
||||
|
||||
Send them the file, or open it for them. They'll click through the walkthroughs and free-play whenever they get to it; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions or a new scenario, add them. Prototypes evolve.
|
||||
|
||||
### 5. Capture the answer and the prototype
|
||||
|
||||
Once the prototype has answered its question, capture the answer, then capture the prototype the way the [SKILL](SKILL.md) describes. The logic-specific mapping: the validated reducer / machine / function set lifts into the real module (the decision, absorbed); the HTML shell rides along to the throwaway branch that keeps the prototype as a primary source — and being one self-contained file, it stays trivially re-runnable there.
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Don't add tests.** A prototype that needs tests is no longer a prototype.
|
||||
- **Don't wire it to the real database.** Use in-memory state unless the question is specifically about persistence.
|
||||
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
|
||||
- **Don't blur the logic and the page together.** If the pure module references the DOM, `document`, or button handlers, it's no longer liftable. Keep the page as a thin shell over a pure module.
|
||||
- **Don't reach for a framework, bundler, or server.** One file the recipient double-clicks; a React app or a dev server defeats "shareable".
|
||||
- **Don't ship the HTML shell into production.** The page is optimised for being clicked through by hand. The logic module behind it is the bit worth keeping.
|
||||
Vendored
-26
@@ -1,26 +0,0 @@
|
||||
---
|
||||
name: prototype
|
||||
description: Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
|
||||
---
|
||||
|
||||
# Prototype
|
||||
|
||||
A prototype is **throwaway code that answers a question**. The question decides the shape.
|
||||
|
||||
## Pick a branch
|
||||
|
||||
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
|
||||
|
||||
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a single shareable HTML file — free-play buttons plus tabbed guided walkthroughs — that pushes the state machine through cases that are hard to reason about on paper, and that a non-developer can drive.
|
||||
- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
|
||||
|
||||
The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype.
|
||||
|
||||
## Rules that apply to both
|
||||
|
||||
1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure.
|
||||
2. **Trivial to run.** A UI prototype starts from one command in the project's task runner — `pnpm <name>`, `python <path>`, `bun <path>`, etc. A logic demo is a single HTML file the user double-clicks. Either way, no thinking required to start it.
|
||||
3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
|
||||
4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast.
|
||||
5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
|
||||
6. **Capture it when done.** Fold any validated decision into the real code, then capture the prototype itself as a **primary source**: commit it to a throwaway branch, out of main, and leave a context pointer to that branch on the implementation issue. Capture the answer too — the verdict and the question it settled — in the issue or a commit. The main branch keeps only the validated decision.
|
||||
Vendored
-112
@@ -1,112 +0,0 @@
|
||||
# UI Prototype
|
||||
|
||||
Generate **several radically different UI variations** on a single route, switchable from a floating bottom bar. The user flips between variants in the browser, picks one (or steals bits from each), then throws the rest away.
|
||||
|
||||
If the question is about logic/state rather than what something looks like — wrong branch. Use [LOGIC.md](LOGIC.md).
|
||||
|
||||
## When this is the right shape
|
||||
|
||||
- "What should this page look like?"
|
||||
- "I want to see a few options for this dashboard before committing."
|
||||
- "Try a different layout for the settings screen."
|
||||
- Any time the user would otherwise spend a day picking between three vague mockups in their head.
|
||||
|
||||
## Two sub-shapes — strongly prefer sub-shape A
|
||||
|
||||
A UI prototype is much easier to judge when it's **butting up against the rest of the app** — real header, real sidebar, real data, real density. A throwaway route on its own is a vacuum: every variant looks fine in isolation. Default to sub-shape A whenever there's a plausible existing page to host the variants. Only reach for sub-shape B if the prototype genuinely has no nearby home.
|
||||
|
||||
### Sub-shape A — adjustment to an existing page (preferred)
|
||||
|
||||
The route already exists. Variants are rendered **on the same route**, gated by a `?variant=` URL search param. The existing data fetching, params, and auth all stay — only the rendering swaps. This is the default; pick it unless there's a specific reason not to.
|
||||
|
||||
If the prototype is for something that doesn't yet have a page but *would naturally live inside one* (a new section of the dashboard, a new card on the settings screen, a new step in an existing flow) — that's still sub-shape A. Mount the variants inside the host page.
|
||||
|
||||
### Sub-shape B — a new page (last resort)
|
||||
|
||||
Only use this when the thing being prototyped genuinely has no existing page to live inside — e.g. an entirely new top-level surface, or a flow that can't be embedded anywhere sensible.
|
||||
|
||||
Create a **throwaway route** following whatever routing convention the project already uses — don't invent a new top-level structure. Name it so it's obviously a prototype (e.g. include the word `prototype` in the path or filename). Same `?variant=` pattern.
|
||||
|
||||
Before committing to sub-shape B, sanity-check: is there really no existing page this could be embedded in? An empty route hides design problems that a populated one would expose.
|
||||
|
||||
In both sub-shapes the floating bottom bar is identical.
|
||||
|
||||
## Process
|
||||
|
||||
### 1. State the question and pick N
|
||||
|
||||
Default to **3 variants**. More than 5 stops being radically different and starts being noise — cap there.
|
||||
|
||||
Write down the plan in one line, in the prototype's location or a top-of-file comment:
|
||||
|
||||
> "Three variants of the settings page, switchable via `?variant=`, on the existing `/settings` route."
|
||||
|
||||
This works whether the user is here to push back or not.
|
||||
|
||||
### 2. Generate radically different variants
|
||||
|
||||
Draft each variant. Hold each one to:
|
||||
|
||||
- The page's purpose and the data it has access to.
|
||||
- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
|
||||
- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
|
||||
|
||||
Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
|
||||
|
||||
### 3. Wire them together
|
||||
|
||||
Create a single switcher component on the route:
|
||||
|
||||
```tsx
|
||||
// pseudo-code — adapt to the project's framework
|
||||
const variant = searchParams.get('variant') ?? 'A';
|
||||
return (
|
||||
<>
|
||||
{variant === 'A' && <VariantA {...data} />}
|
||||
{variant === 'B' && <VariantB {...data} />}
|
||||
{variant === 'C' && <VariantC {...data} />}
|
||||
<PrototypeSwitcher variants={['A','B','C']} current={variant} />
|
||||
</>
|
||||
);
|
||||
```
|
||||
|
||||
For sub-shape A (existing page): keep all the existing data fetching above the switcher; only the rendered subtree changes per variant.
|
||||
|
||||
For sub-shape B (new page): the throwaway route under `/prototype/<name>` mounts the same switcher.
|
||||
|
||||
### 4. Build the floating switcher
|
||||
|
||||
A small fixed-position bar at the bottom-centre of the screen with three pieces:
|
||||
|
||||
- **Left arrow** — cycles to the previous variant (wraps around).
|
||||
- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`.
|
||||
- **Right arrow** — cycles forward (wraps around).
|
||||
|
||||
Behaviour:
|
||||
|
||||
- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable.
|
||||
- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an `<input>`, `<textarea>`, or `[contenteditable]` is focused.
|
||||
- Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it's obviously not part of the design being evaluated.
|
||||
- Hidden in production builds — gate on `process.env.NODE_ENV !== 'production'` or an equivalent check, so a stray prototype merge can't ship the bar to users.
|
||||
|
||||
Put the switcher in a single shared component so both sub-shapes can reuse it. Locate it wherever shared UI lives in the project.
|
||||
|
||||
### 5. Hand it over
|
||||
|
||||
Surface the URL (and the `?variant=` keys). The user will flip through whenever they get to it. The interesting feedback is usually **"I want the header from B with the sidebar from C"** — that's the actual design they want.
|
||||
|
||||
### 6. Capture the answer and clean up
|
||||
|
||||
Once a variant has won, capture the answer — which variant and why — then capture the prototype the way the [SKILL](SKILL.md) describes. Fold the winner into the real code and move the rest onto the throwaway branch, not into main:
|
||||
|
||||
- **Sub-shape A** — fold the winner into the existing page; drop the losing variants and the switcher from main.
|
||||
- **Sub-shape B** — promote the winning variant to a real route; drop the throwaway route and the switcher from main.
|
||||
|
||||
The full set of variants is the primary source, so it lands on the throwaway branch, not the bin — variant components and the switcher left in the main branch rot fast and confuse the next reader.
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree about structure.
|
||||
- **Sharing too much code between variants.** A shared `<Header>` is fine; a shared `<Layout>` defeats the point. Each variant should be free to throw out the layout.
|
||||
- **Wiring variants to real mutations.** Read-only prototypes are fine. If a variant needs to mutate, point it at a stub — the question is "what should this look like", not "does the backend work".
|
||||
- **Promoting the prototype directly to production.** The variant code was written under prototype constraints (no tests, minimal error handling). Rewrite it properly when you fold it in.
|
||||
@@ -1,3 +0,0 @@
|
||||
interface:
|
||||
display_name: "Prototype"
|
||||
short_description: "Prototype to answer a design question"
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
---
|
||||
name: scaffold-exercises
|
||||
description: Create exercise directory structures with sections, problems, solutions, and explainers that pass linting. Use when user wants to scaffold exercises, create exercise stubs, or set up a new course section.
|
||||
---
|
||||
|
||||
# Scaffold Exercises
|
||||
|
||||
Create exercise directory structures that pass `pnpm ai-hero-cli internal lint`, then commit with `git commit`.
|
||||
|
||||
## Directory naming
|
||||
|
||||
- **Sections**: `XX-section-name/` inside `exercises/` (e.g., `01-retrieval-skill-building`)
|
||||
- **Exercises**: `XX.YY-exercise-name/` inside a section (e.g., `01.03-retrieval-with-bm25`)
|
||||
- Section number = `XX`, exercise number = `XX.YY`
|
||||
- Names are dash-case (lowercase, hyphens)
|
||||
|
||||
## Exercise variants
|
||||
|
||||
Each exercise needs at least one of these subfolders:
|
||||
|
||||
- `problem/` - student workspace with TODOs
|
||||
- `solution/` - reference implementation
|
||||
- `explainer/` - conceptual material, no TODOs
|
||||
|
||||
When stubbing, default to `explainer/` unless the plan specifies otherwise.
|
||||
|
||||
## Required files
|
||||
|
||||
Each subfolder (`problem/`, `solution/`, `explainer/`) needs a `readme.md` that:
|
||||
|
||||
- Is **not empty** (must have real content, even a single title line works)
|
||||
- Has no broken links
|
||||
|
||||
When stubbing, create a minimal readme with a title and a description:
|
||||
|
||||
```md
|
||||
# Exercise Title
|
||||
|
||||
Description here
|
||||
```
|
||||
|
||||
If the subfolder has code, it also needs a `main.ts` (>1 line). But for stubs, a readme-only exercise is fine.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Parse the plan** - extract section names, exercise names, and variant types
|
||||
2. **Create directories** - `mkdir -p` for each path
|
||||
3. **Create stub readmes** - one `readme.md` per variant folder with a title
|
||||
4. **Run lint** - `pnpm ai-hero-cli internal lint` to validate
|
||||
5. **Fix any errors** - iterate until lint passes
|
||||
|
||||
## Lint rules summary
|
||||
|
||||
The linter (`pnpm ai-hero-cli internal lint`) checks:
|
||||
|
||||
- Each exercise has subfolders (`problem/`, `solution/`, `explainer/`)
|
||||
- At least one of `problem/`, `explainer/`, or `explainer.1/` exists
|
||||
- `readme.md` exists and is non-empty in the primary subfolder
|
||||
- No `.gitkeep` files
|
||||
- No `speaker-notes.md` files
|
||||
- No broken links in readmes
|
||||
- No `pnpm run exercise` commands in readmes
|
||||
- `main.ts` required per subfolder unless it's readme-only
|
||||
|
||||
## Moving/renaming exercises
|
||||
|
||||
When renumbering or moving exercises:
|
||||
|
||||
1. Use `git mv` (not `mv`) to rename directories - preserves git history
|
||||
2. Update the numeric prefix to maintain order
|
||||
3. Re-run lint after moves
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
git mv exercises/01-retrieval/01.03-embeddings exercises/01-retrieval/01.04-embeddings
|
||||
```
|
||||
|
||||
## Example: stubbing from a plan
|
||||
|
||||
Given a plan like:
|
||||
|
||||
```
|
||||
Section 05: Memory Skill Building
|
||||
- 05.01 Introduction to Memory
|
||||
- 05.02 Short-term Memory (explainer + problem + solution)
|
||||
- 05.03 Long-term Memory
|
||||
```
|
||||
|
||||
Create:
|
||||
|
||||
```bash
|
||||
mkdir -p exercises/05-memory-skill-building/05.01-introduction-to-memory/explainer
|
||||
mkdir -p exercises/05-memory-skill-building/05.02-short-term-memory/{explainer,problem,solution}
|
||||
mkdir -p exercises/05-memory-skill-building/05.03-long-term-memory/explainer
|
||||
```
|
||||
|
||||
Then create readme stubs:
|
||||
|
||||
```
|
||||
exercises/05-memory-skill-building/05.01-introduction-to-memory/explainer/readme.md -> "# Introduction to Memory"
|
||||
exercises/05-memory-skill-building/05.02-short-term-memory/explainer/readme.md -> "# Short-term Memory"
|
||||
exercises/05-memory-skill-building/05.02-short-term-memory/problem/readme.md -> "# Short-term Memory"
|
||||
exercises/05-memory-skill-building/05.02-short-term-memory/solution/readme.md -> "# Short-term Memory"
|
||||
exercises/05-memory-skill-building/05.03-long-term-memory/explainer/readme.md -> "# Long-term Memory"
|
||||
```
|
||||
@@ -1,3 +0,0 @@
|
||||
interface:
|
||||
display_name: "Scaffold Exercises"
|
||||
short_description: "Scaffold lint-ready course exercises"
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
---
|
||||
name: setup-pre-commit
|
||||
description: Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.
|
||||
---
|
||||
|
||||
# Setup Pre-Commit Hooks
|
||||
|
||||
## What This Sets Up
|
||||
|
||||
- **Husky** pre-commit hook
|
||||
- **lint-staged** running Prettier on all staged files
|
||||
- **Prettier** config (if missing)
|
||||
- **typecheck** and **test** scripts in the pre-commit hook
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Detect package manager
|
||||
|
||||
Check for `package-lock.json` (npm), `pnpm-lock.yaml` (pnpm), `yarn.lock` (yarn), `bun.lockb` (bun). Use whichever is present. Default to npm if unclear.
|
||||
|
||||
### 2. Install dependencies
|
||||
|
||||
Install as devDependencies:
|
||||
|
||||
```
|
||||
husky lint-staged prettier
|
||||
```
|
||||
|
||||
### 3. Initialize Husky
|
||||
|
||||
```bash
|
||||
npx husky init
|
||||
```
|
||||
|
||||
This creates `.husky/` dir and adds `prepare: "husky"` to package.json.
|
||||
|
||||
### 4. Create `.husky/pre-commit`
|
||||
|
||||
Write this file (no shebang needed for Husky v9+):
|
||||
|
||||
```
|
||||
npx lint-staged
|
||||
npm run typecheck
|
||||
npm run test
|
||||
```
|
||||
|
||||
**Adapt**: Replace `npm` with detected package manager. If repo has no `typecheck` or `test` script in package.json, omit those lines and tell the user.
|
||||
|
||||
### 5. Create `.lintstagedrc`
|
||||
|
||||
```json
|
||||
{
|
||||
"*": "prettier --ignore-unknown --write"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Create `.prettierrc` (if missing)
|
||||
|
||||
Only create if no Prettier config exists. Use these defaults:
|
||||
|
||||
```json
|
||||
{
|
||||
"useTabs": false,
|
||||
"tabWidth": 2,
|
||||
"printWidth": 80,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"semi": true,
|
||||
"arrowParens": "always"
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Verify
|
||||
|
||||
- [ ] `.husky/pre-commit` exists and is executable
|
||||
- [ ] `.lintstagedrc` exists
|
||||
- [ ] `prepare` script in package.json is `"husky"`
|
||||
- [ ] `prettier` config exists
|
||||
- [ ] Run `npx lint-staged` to verify it works
|
||||
|
||||
### 8. Commit
|
||||
|
||||
Stage all changed/created files and commit with message: `Add pre-commit hooks (husky + lint-staged + prettier)`
|
||||
|
||||
This will run through the new pre-commit hooks — a good smoke test that everything works.
|
||||
|
||||
## Notes
|
||||
|
||||
- Husky v9+ doesn't need shebangs in hook files
|
||||
- `prettier --ignore-unknown` skips files Prettier can't parse (images, etc.)
|
||||
- The pre-commit runs lint-staged first (fast, staged-only), then full typecheck and tests
|
||||
@@ -1,3 +0,0 @@
|
||||
interface:
|
||||
display_name: "Setup Pre-Commit"
|
||||
short_description: "Add pre-commit quality checks"
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
# GLOSSARY.md Format
|
||||
|
||||
`GLOSSARY.md` is the canonical language for this teaching workspace. All explainers, exercises, and learning records should adhere to its terminology. Building it is itself part of learning: compressing a concept into a tight definition is evidence the user understands it.
|
||||
|
||||
## Structure
|
||||
|
||||
```md
|
||||
# {Topic} Glossary
|
||||
|
||||
{One or two sentence description of the topic this glossary covers.}
|
||||
|
||||
## Terms
|
||||
|
||||
**Hypertrophy**:
|
||||
Muscle growth driven by mechanical tension and metabolic stress over repeated training sessions.
|
||||
_Avoid_: Bulking, getting big
|
||||
|
||||
**Progressive overload**:
|
||||
Systematically increasing the demand on a muscle over time — via load, volume, or intensity.
|
||||
_Avoid_: Pushing harder, levelling up
|
||||
|
||||
**RPE (Rate of Perceived Exertion)**:
|
||||
A 1–10 self-rating of how hard a set felt, where 10 is failure and 8 means two reps left in the tank.
|
||||
_Avoid_: Effort score, intensity rating
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **Add a term only when the user understands it.** The glossary is a record of compressed knowledge, not a dictionary the user reads to learn. If the user has just been introduced to a concept, wait until they can use it correctly before promoting it here.
|
||||
- **Be opinionated.** When several words exist for the same concept, pick the best one and list the rest as aliases to avoid. This is how language compresses.
|
||||
- **Keep definitions tight.** One or two sentences. Define what the term IS, not what it does or how to do it.
|
||||
- **Use the glossary's own terms inside definitions.** Once a term is in the glossary, prefer it everywhere — including inside other definitions. This is what makes complex terms easier to grasp later.
|
||||
- **Group under subheadings** when natural clusters emerge (e.g. `## Anatomy`, `## Programming`). A flat list is fine when terms cohere.
|
||||
- **Flag ambiguities explicitly.** If a term is used loosely in the wider field, note the resolution: "In this workspace, 'set' always means a working set — warm-ups are tracked separately."
|
||||
- **Revise as understanding deepens.** A definition the user wrote in week one may be wrong by week six. Update in place; do not leave stale entries.
|
||||
@@ -1,46 +0,0 @@
|
||||
# Learning Record Format
|
||||
|
||||
Learning records live in `./learning-records/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc. Create the directory lazily — only when the first record is written.
|
||||
|
||||
They are the teaching equivalent of ADRs: they capture non-obvious lessons, key insights, and stated prior knowledge that will steer future sessions. They are used to calculate the zone of proximal development.
|
||||
|
||||
## Template
|
||||
|
||||
```md
|
||||
# {Short title of what was learned or established}
|
||||
|
||||
{1-3 sentences: what was learned (or what prior knowledge was established), and why it matters for future sessions.}
|
||||
```
|
||||
|
||||
That is the whole format. A learning record can be a single paragraph. The value is recording _that_ this is now known and _why_ it changes what to teach next — not in filling out sections.
|
||||
|
||||
## Optional sections
|
||||
|
||||
Only include these when they add genuine value. Most records won't need them.
|
||||
|
||||
- **Status** frontmatter (`active | superseded by LR-NNNN`) — useful when an earlier understanding turns out to be wrong and is replaced.
|
||||
- **Evidence** — how the user demonstrated the understanding (a question answered, an exercise completed, prior experience cited). Useful when the claim might be revisited.
|
||||
- **Implications** — what this unlocks or rules out for future sessions. Worth recording when non-obvious.
|
||||
|
||||
## Numbering
|
||||
|
||||
Scan `./learning-records/` for the highest existing number and increment by one.
|
||||
|
||||
## When to write a learning record
|
||||
|
||||
Write one when any of these is true:
|
||||
|
||||
1. **The user demonstrated genuine understanding of something non-trivial** — not just exposure, but evidence they can use the concept correctly. This sets a new floor for what to teach next.
|
||||
2. **The user disclosed prior knowledge** — "I already know X." Record it so future sessions don't re-teach it. Also record the _depth_ claimed.
|
||||
3. **A misconception was corrected** — the user previously believed something wrong and now sees why. These are high-value: they predict future stumbling blocks for related topics.
|
||||
4. **The mission shifted in response to learning** — the user discovered they cared about something different than they thought. Cross-link to [[MISSION.md]] and update it.
|
||||
|
||||
### What does _not_ qualify
|
||||
|
||||
- Material that was merely covered. Coverage is not learning. Wait for evidence.
|
||||
- Anything already captured tersely in [[GLOSSARY.md]] as a term definition. Don't duplicate.
|
||||
- Session-by-session activity logs. Learning records are not a journal — they are decision-grade insights.
|
||||
|
||||
## Supersession
|
||||
|
||||
When a later record contradicts an earlier one (the user's understanding deepened or corrected), mark the old record `Status: superseded by LR-NNNN` rather than deleting it. The history of how understanding evolved is itself useful signal.
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
# MISSION.md Format
|
||||
|
||||
`MISSION.md` lives at the workspace root. It captures the _reason_ the user is learning this topic. Every teaching decision — what to teach next, which resources to surface, which exercises to design — should trace back to this document.
|
||||
|
||||
## Template
|
||||
|
||||
```md
|
||||
# Mission: {Topic}
|
||||
|
||||
## Why
|
||||
{1-3 sentences. The concrete real-world goal the user is chasing. What changes in their life or work when they have this skill? Avoid abstract framings like "to understand X" — push for the underlying outcome.}
|
||||
|
||||
## Success looks like
|
||||
- {A specific, observable thing the user will be able to do}
|
||||
- {Another specific thing}
|
||||
- {…}
|
||||
|
||||
## Constraints
|
||||
- {Time, budget, prior commitments, learning preferences, anything that bounds the approach}
|
||||
|
||||
## Out of scope
|
||||
- {Adjacent topics the user explicitly does not want to chase right now — protects the zone of proximal development}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **One mission per workspace.** If the user wants to learn two unrelated things, that is two workspaces.
|
||||
- **Concrete over abstract.** "Run a half marathon by October" beats "get fitter." "Ship a Rust CLI to my team" beats "learn Rust."
|
||||
- **Push back on vagueness.** If the user cannot articulate why, interview them before writing anything. A bad mission is worse than no mission.
|
||||
- **Revise when reality shifts.** Missions change. When the user's goal moves, update this file — don't leave a stale mission steering future sessions.
|
||||
- **Keep it short.** If `MISSION.md` runs past a screen, it has stopped being a compass and started being a plan.
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
# RESOURCES.md Format
|
||||
|
||||
`RESOURCES.md` is the curated set of trusted sources for this topic. Knowledge for explainers should be drawn from here, not from parametric guesses. Wisdom comes from the communities listed here.
|
||||
|
||||
## Structure
|
||||
|
||||
```md
|
||||
# {Topic} Resources
|
||||
|
||||
## Knowledge
|
||||
|
||||
- [Book: _The Science and Practice of Strength Training_ — Zatsiorsky & Kraemer](https://example.com)
|
||||
Foundational text on programming and adaptation. Use for: anything to do with periodisation, recovery, intensity zones.
|
||||
- [Article: "How Much Should I Train?" — Greg Nuckols (Stronger By Science)](https://example.com)
|
||||
Evidence-based review of volume landmarks. Use for: weekly set targets per muscle group.
|
||||
|
||||
## Wisdom (Communities)
|
||||
|
||||
- [r/weightroom](https://reddit.com/r/weightroom)
|
||||
High-signal subreddit, moderated against bro-science. Use for: programme critique, plateau troubleshooting.
|
||||
- Local: Tuesday strength class at {gym name}
|
||||
Use for: real-time coaching feedback on lifts.
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **High-trust only.** Prefer primary sources, recognised experts, peer-reviewed work, and communities with strong moderation. If a resource is marketing dressed as education, leave it out.
|
||||
- **Annotate every entry.** A bare link is useless in three months. Add one line: what it covers and when to reach for it.
|
||||
- **Group by Knowledge / Wisdom.** Mirrors the philosophy in [SKILL.md](./SKILL.md). It is fine for a resource to appear in only one group.
|
||||
- **Surface gaps explicitly.** If no good resource exists for an area the mission needs, write a `## Gaps` section listing what is missing. This drives future search.
|
||||
- **Prune ruthlessly.** A resource that turned out to be wrong, shallow, or off-mission should be removed, not buried. Better five sharp sources than thirty mediocre ones.
|
||||
- **Record community preferences.** If the user has opted out of joining communities, note it here so future sessions don't keep proposing them.
|
||||
Vendored
-140
@@ -1,140 +0,0 @@
|
||||
---
|
||||
name: teach
|
||||
description: Teach the user a new skill or concept, within this workspace.
|
||||
disable-model-invocation: true
|
||||
argument-hint: "What would you like to learn about?"
|
||||
---
|
||||
|
||||
The user has asked you to teach them something. This is a stateful request - they intend to learn the topic over multiple sessions.
|
||||
|
||||
## Teaching Workspace
|
||||
|
||||
Treat the current directory as a teaching workspace. The state of their learning is captured in this directory in several files:
|
||||
|
||||
- `MISSION.md`: A document capturing the _reason_ the user is interested in the topic. This should be used to ground all teaching. Use the format in [MISSION-FORMAT.md](./MISSION-FORMAT.md).
|
||||
- `./reference/*.html`: A directory of reference materials. These are the compressed learnings from the lessons - cheat sheets, reference algorithms, syntax, yoga poses, glossaries. They are the raw units of learning. They should be beautiful documents which print out well, and are designed for quick reference.
|
||||
- `RESOURCES.md`: A list of resources which can be explored to ground your teaching in contextual knowledge, or to acquire knowledge and wisdom. Use the format in [RESOURCES-FORMAT.md](./RESOURCES-FORMAT.md).
|
||||
- `./learning-records/*.md`: A directory of learning records, which capture what the user has learned. These are loosely equivalent to architectural decision records in software development - they capture non-obvious lessons and key insights that may need to be revised later, or drive future sessions. These should be used to calculate the zone of proximal development. They are titled `0001-<dash-case-name>.md`, where the number increments each time. Use the format in [LEARNING-RECORD-FORMAT.md](./LEARNING-RECORD-FORMAT.md).
|
||||
- `./lessons/*.html`: A directory of lessons. A **lesson** is a single, self-contained HTML output that teaches one tightly-scoped thing tied to the mission. This is the primary unit of teaching in this workspace.
|
||||
- `./assets/*`: Reusable **components** shared across lessons. See [Assets](#assets).
|
||||
- `NOTES.md`: A scratchpad for you to jot down user preferences, or working notes.
|
||||
|
||||
## Philosophy
|
||||
|
||||
To learn at a deep level, the user needs three things:
|
||||
|
||||
- **Knowledge**, captured from high-quality, high-trust resources
|
||||
- **Skills**, acquired through highly-relevant interactive lessons devised by you, based on the knowledge
|
||||
- **Wisdom**, which comes from interacting with other learners and practitioners
|
||||
|
||||
Before the `RESOURCES.md` is well-populated, your focus should be to find high-quality resources which will help the user acquire knowledge. Never trust your parametric knowledge.
|
||||
|
||||
Some topics may require more skills than knowledge. Learning more about theoretical physics might be more knowledge-based. For yoga, more skills-based.
|
||||
|
||||
### Fluency vs Storage Strength
|
||||
|
||||
You should be careful to split between two types of learning:
|
||||
|
||||
- **Fluency strength**: in-the-moment retrieval of knowledge
|
||||
- **Storage strength**: long-term retention of knowledge
|
||||
|
||||
Fluency can give the user an illusory sense of mastery, but storage strength is the real goal. Try to design lessons which build long-term retention by desirable difficulty:
|
||||
|
||||
- Using retrieval practice (recall from memory)
|
||||
- Spacing (distributing practice over time)
|
||||
- Interleaving (mixing up different but related topics in practice - for skills practice only)
|
||||
|
||||
## Lessons
|
||||
|
||||
A lesson is the main thing you produce — the unit in which knowledge and skills reach the user. Each lesson is one self-contained HTML file, saved to `./lessons/` and titled `0001-<dash-case-name>.html` where the number increments each time.
|
||||
|
||||
A lesson should be **beautiful** — clean, readable typography and layout — since the user will return to these later to review. Think Tufte.
|
||||
|
||||
The lesson should be short, and completable very quickly. Learners' working memory is very small, and we need to stay within it. But each lesson should give the user a single tangible win that they can build on. It should be directly tied to the mission, and should be in the user's zone of proximal development.
|
||||
|
||||
If possible, open the lesson file for the user by running a CLI command.
|
||||
|
||||
Each lesson should link via HTML anchors to other lessons and reference documents.
|
||||
|
||||
Each lesson should recommend a primary source for the user to read or watch. This should be the most high-quality, high-trust resource you found on the topic.
|
||||
|
||||
Each lesson should contain a reminder to ask followup questions to the agent. The agent is their teacher, and can assist with anything that's unclear.
|
||||
|
||||
## Assets
|
||||
|
||||
Lessons are built from reusable **components**, stored in `./assets/`: stylesheets, quiz widgets, simulators, diagram helpers — anything a second lesson could reuse.
|
||||
|
||||
Reuse is the default, not the exception. Before authoring a lesson, read `./assets/` and build from the components already there. When a lesson needs something new and reusable, write it as a component in `./assets/` and link to it — never inline code a future lesson would duplicate.
|
||||
|
||||
A shared stylesheet is the first component every workspace earns: every lesson links it, so the lessons look like one consistent course rather than a pile of one-offs. As the workspace grows, so should the component library.
|
||||
|
||||
## The Mission
|
||||
|
||||
Every lesson should be tied into the mission - the reason that the user is interested in learning about the topic.
|
||||
|
||||
If the user is unclear about the mission, or the `MISSION.md` is not populated, your first job should be to question the user on why they want to learn this.
|
||||
|
||||
Failing to understand the mission will mean knowledge acquisition is not grounded in real-world goals. Lessons will feel too abstract. You will have no way of judging what the user should do next.
|
||||
|
||||
Missions may change as the user develops more skills and knowledge. This is normal - make sure to update the `MISSION.md` and add a learning record to capture the change. Confirm with the user before changing the mission.
|
||||
|
||||
## Zone Of Proximal Development
|
||||
|
||||
Each lesson, the user should always feel as if they are being challenged 'just enough'.
|
||||
|
||||
The user may specify an exact thing they want to learn. If they don't, figure out their zone of proximal development by:
|
||||
|
||||
- Reading their `learning-records`
|
||||
- Figuring out the right thing to teach them based on their mission
|
||||
- Teach the most relevant thing that fits in their zone of proximal development
|
||||
|
||||
## Knowledge
|
||||
|
||||
Lessons should be designed around a skill the user is going to learn. The knowledge in the lesson should be only what's required to acquire that skill. You teach the knowledge first, then get the user to practice the skills via an interactive feedback loop.
|
||||
|
||||
Knowledge should first be gathered from trusted resources. Use `RESOURCES.md` to keep track of them. Lessons should be littered with citations - links to external resources to back up any claim made. This increases the trustworthiness of the lesson.
|
||||
|
||||
For acquiring knowledge, difficulty is the enemy. It eats working memory you need for understanding.
|
||||
|
||||
## Skills
|
||||
|
||||
If knowledge is all about acquisition, skills are about durability and flexibility. Make the knowledge stick.
|
||||
|
||||
For skill acquisition, difficulty is the tool. Effortful retrieval is what builds storage strength. Skills should be taught through interactive lessons. There are several tools at your disposal:
|
||||
|
||||
- Interactive lessons, using quizzes and light in-browser tasks
|
||||
- Lessons which guide the user through a list of real-world steps to take (for instance, yoga poses)
|
||||
|
||||
Each of these should be based on a **feedback loop**, where the user receives feedback on their performance. This feedback loop should be as tight as possible, giving feedback immediately - and ideally automatically.
|
||||
|
||||
For quizzes, each answer should be exactly the same number of words (and characters, if possible). Don't give the user any clues about the answer through formatting.
|
||||
|
||||
## Acquiring Wisdom
|
||||
|
||||
Wisdom comes from true real-world interaction - testing your skills outside the learning environment.
|
||||
|
||||
When the user asks a question that appears to require wisdom, your default posture should be to attempt to answer - but to ultimately delegate to a **community**.
|
||||
|
||||
A community is a place (online or offline) where the user can test their skills in the real world. This might be a forum, a subreddit, a real-world class (budget permitting) or a local interest group.
|
||||
|
||||
You should attempt to find high-reputation communities the user can join. If the user expresses a preference that they don't want to join a community, respect it.
|
||||
|
||||
## Reference Documents
|
||||
|
||||
While creating lessons, you should also create reference documents. Lessons can reference these documents - they are useful for tracking raw units of knowledge useful across lessons.
|
||||
|
||||
Lessons will rarely be revisited later - reference documents will be. They should be the compressed essence of the lesson, in a format designed for quick reference.
|
||||
|
||||
Some learning topics lend themselves to reference:
|
||||
|
||||
- Syntax and code snippets for programming
|
||||
- Algorithms and flowcharts for processes
|
||||
- Yoga poses and sequences for yoga
|
||||
- Exercises and routines for fitness
|
||||
- Glossaries for any topic with its own nomenclature
|
||||
|
||||
Glossaries, in particular, are an essential reference. Once one is created, it should be adhered to in every lesson.
|
||||
|
||||
## `NOTES.md`
|
||||
|
||||
The user will sometimes express preferences of how they want to be taught, or things you should keep in mind. This is the place to record those preferences, so you can refer back to them when designing lessons or working with the user.
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
interface:
|
||||
display_name: "Teach"
|
||||
short_description: "Learn a concept in a guided workspace"
|
||||
policy:
|
||||
allow_implicit_invocation: false
|
||||
+110
-2
@@ -77,6 +77,108 @@ def _resolve_dial(dial_name: str, value) -> dict:
|
||||
return None
|
||||
|
||||
|
||||
# ============ COLOR MODE RESOLUTION ============
|
||||
# Style, palette and anti-patterns are resolved from separate CSVs. Without a
|
||||
# shared notion of "which mode did we land on", a dark-primary style can be
|
||||
# paired with a light palette and a "don't use dark mode" anti-pattern.
|
||||
|
||||
# Phrases in styles.csv "Light Mode ✓" / "Dark Mode ✓" that mark a style as
|
||||
# dark-first rather than merely dark-capable ("✓ Full" means both work).
|
||||
_DARK_PRIMARY_MARKERS = (
|
||||
"dark mode primary", "dark primary", "dark-only", "dark only",
|
||||
"dark preferred", "dark focused", "dark-first", "dark rich",
|
||||
"light mode only as exception",
|
||||
)
|
||||
|
||||
# Query phrases that are an explicit request for a dark theme.
|
||||
_DARK_QUERY_MARKERS = (
|
||||
"dark mode", "dark theme", "dark ui", "dark-mode", "darkmode",
|
||||
"night mode", "midnight", "oled",
|
||||
)
|
||||
|
||||
# Anti-pattern clauses that contradict a resolved dark mode.
|
||||
_DARK_ANTI_PATTERN_MARKERS = ("dark mode", "dark modes", "dark theme")
|
||||
|
||||
# Relative luminance below which a Background hex counts as a dark surface.
|
||||
# #1F2937 (the lightest dark background in colors.csv) sits at ~0.026 and
|
||||
# #E8ECF1 (the darkest light background) at ~0.79, so the gap is wide.
|
||||
_DARK_BACKGROUND_MAX_LUMINANCE = 0.18
|
||||
|
||||
|
||||
def _relative_luminance(hex_color: str):
|
||||
"""WCAG relative luminance of a #RRGGBB string, or None if unparseable."""
|
||||
if not hex_color:
|
||||
return None
|
||||
value = hex_color.strip().lstrip("#")
|
||||
if len(value) == 3:
|
||||
value = "".join(c * 2 for c in value)
|
||||
if len(value) != 6:
|
||||
return None
|
||||
try:
|
||||
channels = [int(value[i:i + 2], 16) / 255 for i in (0, 2, 4)]
|
||||
except ValueError:
|
||||
return None
|
||||
linear = [c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4
|
||||
for c in channels]
|
||||
return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2]
|
||||
|
||||
|
||||
def _palette_is_dark(palette: dict) -> bool:
|
||||
"""True when a colors.csv row's Background is a dark surface."""
|
||||
luminance = _relative_luminance((palette or {}).get("Background", ""))
|
||||
return luminance is not None and luminance < _DARK_BACKGROUND_MAX_LUMINANCE
|
||||
|
||||
|
||||
def _style_is_dark_primary(style: dict) -> bool:
|
||||
"""True when a styles.csv row describes itself as dark-first."""
|
||||
if not style:
|
||||
return False
|
||||
declared = "{} {}".format(
|
||||
style.get("Light Mode ✓", ""), style.get("Dark Mode ✓", "")
|
||||
).lower()
|
||||
return any(marker in declared for marker in _DARK_PRIMARY_MARKERS)
|
||||
|
||||
|
||||
def _query_wants_dark(query: str) -> bool:
|
||||
"""True when the query explicitly asks for a dark theme."""
|
||||
lowered = (query or "").lower()
|
||||
return any(marker in lowered for marker in _DARK_QUERY_MARKERS)
|
||||
|
||||
|
||||
def _resolve_color_mode(query: str, style: dict) -> str:
|
||||
"""Resolve the mode the rest of the output has to agree with."""
|
||||
if _query_wants_dark(query) or _style_is_dark_primary(style):
|
||||
return "dark"
|
||||
return "light"
|
||||
|
||||
|
||||
def _select_palette_for_mode(palettes: list, mode: str) -> dict:
|
||||
"""Pick the highest-ranked palette matching the resolved mode.
|
||||
|
||||
Only the dark case filters. Light is left on the existing "top hit wins"
|
||||
behaviour so queries that never mention a mode keep their current palette.
|
||||
Falls back to the top hit when the data has no matching ramp.
|
||||
"""
|
||||
if not palettes:
|
||||
return {}
|
||||
if mode == "dark":
|
||||
for palette in palettes:
|
||||
if _palette_is_dark(palette):
|
||||
return palette
|
||||
return palettes[0]
|
||||
|
||||
|
||||
def _filter_anti_patterns_for_mode(anti_patterns: str, mode: str) -> str:
|
||||
"""Drop "avoid dark mode" advice once dark mode is the resolved answer."""
|
||||
if mode != "dark" or not anti_patterns:
|
||||
return anti_patterns
|
||||
kept = [
|
||||
clause for clause in anti_patterns.split("+")
|
||||
if not any(marker in clause.lower() for marker in _DARK_ANTI_PATTERN_MARKERS)
|
||||
]
|
||||
return " + ".join(clause.strip() for clause in kept if clause.strip())
|
||||
|
||||
|
||||
# ============ DESIGN SYSTEM GENERATOR ============
|
||||
class DesignSystemGenerator:
|
||||
"""Generates design system recommendations from aggregated searches."""
|
||||
@@ -244,7 +346,11 @@ class DesignSystemGenerator:
|
||||
landing_results = self._extract_results(search_results.get("landing", {}))
|
||||
|
||||
best_style = self._select_best_match(style_results, effective_style_priority)
|
||||
best_color = color_results[0] if color_results else {}
|
||||
# Resolve the mode from the style + query first, then pick a palette that
|
||||
# agrees with it. Ranking colors independently is what let a dark-primary
|
||||
# style ship with a light background.
|
||||
color_mode = _resolve_color_mode(query, best_style)
|
||||
best_color = _select_palette_for_mode(color_results, color_mode)
|
||||
best_typography = typography_results[0] if typography_results else {}
|
||||
best_landing = landing_results[0] if landing_results else {}
|
||||
|
||||
@@ -313,7 +419,9 @@ class DesignSystemGenerator:
|
||||
"css_import": best_typography.get("CSS Import", "")
|
||||
},
|
||||
"key_effects": combined_effects,
|
||||
"anti_patterns": reasoning.get("anti_patterns", ""),
|
||||
"anti_patterns": _filter_anti_patterns_for_mode(
|
||||
reasoning.get("anti_patterns", ""), color_mode
|
||||
),
|
||||
"decision_rules": reasoning.get("decision_rules", {}),
|
||||
"severity": reasoning.get("severity", "MEDIUM"),
|
||||
"dials": {
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Regression tests for color-mode coherence in design_system.py (issue #428).
|
||||
|
||||
Style, palette and anti-patterns used to be resolved independently, so a
|
||||
dark-primary style could be returned alongside a light palette and a
|
||||
"Dark mode by default" anti-pattern.
|
||||
|
||||
Stdlib-only (unittest, not pytest) to match test_core.py -- this project ships
|
||||
with zero external dependencies.
|
||||
|
||||
Run with:
|
||||
python -m unittest discover -s scripts/tests -v
|
||||
or directly:
|
||||
python scripts/tests/test_design_system_mode.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPTS_DIR = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(SCRIPTS_DIR))
|
||||
|
||||
from design_system import ( # noqa: E402
|
||||
_filter_anti_patterns_for_mode,
|
||||
_palette_is_dark,
|
||||
_query_wants_dark,
|
||||
_relative_luminance,
|
||||
_resolve_color_mode,
|
||||
_select_palette_for_mode,
|
||||
_style_is_dark_primary,
|
||||
DesignSystemGenerator,
|
||||
) # noqa: I001 - private helpers first, public class last
|
||||
|
||||
LIGHT_PALETTE = {"Product Type": "SaaS", "Background": "#F8FAFC", "Foreground": "#020617"}
|
||||
DARK_PALETTE = {"Product Type": "Fintech/Crypto", "Background": "#0F172A", "Foreground": "#F8FAFC"}
|
||||
|
||||
# Verbatim from styles.csv row "Modern Dark (Cinema Mobile)".
|
||||
DARK_PRIMARY_STYLE = {
|
||||
"Style Category": "Modern Dark (Cinema Mobile)",
|
||||
"Light Mode ✓": "✓ Light mode only as exception",
|
||||
"Dark Mode ✓": "✓ Dark Mode Primary",
|
||||
}
|
||||
DUAL_MODE_STYLE = {
|
||||
"Style Category": "Minimalism",
|
||||
"Light Mode ✓": "✓ Full",
|
||||
"Dark Mode ✓": "✓ Full",
|
||||
}
|
||||
|
||||
|
||||
class TestLuminance(unittest.TestCase):
|
||||
def test_parses_six_and_three_digit_hex(self):
|
||||
self.assertAlmostEqual(_relative_luminance("#FFFFFF"), 1.0, places=6)
|
||||
self.assertAlmostEqual(_relative_luminance("#000000"), 0.0, places=6)
|
||||
self.assertAlmostEqual(_relative_luminance("#FFF"), 1.0, places=6)
|
||||
|
||||
def test_returns_none_for_unparseable(self):
|
||||
for value in ("", "nope", "#12", "#GGGGGG", None):
|
||||
self.assertIsNone(_relative_luminance(value))
|
||||
|
||||
def test_classifies_backgrounds_from_the_shipped_data(self):
|
||||
# Lightest dark background and darkest light background in colors.csv.
|
||||
self.assertTrue(_palette_is_dark({"Background": "#1F2937"}))
|
||||
self.assertFalse(_palette_is_dark({"Background": "#E8ECF1"}))
|
||||
|
||||
def test_missing_background_is_not_dark(self):
|
||||
self.assertFalse(_palette_is_dark({}))
|
||||
self.assertFalse(_palette_is_dark(None))
|
||||
|
||||
|
||||
class TestModeResolution(unittest.TestCase):
|
||||
def test_dark_primary_style_detected(self):
|
||||
self.assertTrue(_style_is_dark_primary(DARK_PRIMARY_STYLE))
|
||||
|
||||
def test_dual_mode_style_is_not_dark_primary(self):
|
||||
self.assertFalse(_style_is_dark_primary(DUAL_MODE_STYLE))
|
||||
self.assertFalse(_style_is_dark_primary({}))
|
||||
|
||||
def test_query_keywords(self):
|
||||
self.assertTrue(_query_wants_dark("fintech B2B professional dark mode"))
|
||||
self.assertTrue(_query_wants_dark("gaming app OLED"))
|
||||
self.assertFalse(_query_wants_dark("healthcare clinic booking app"))
|
||||
self.assertFalse(_query_wants_dark(""))
|
||||
|
||||
def test_either_signal_resolves_dark(self):
|
||||
self.assertEqual(_resolve_color_mode("saas dark mode", DUAL_MODE_STYLE), "dark")
|
||||
self.assertEqual(_resolve_color_mode("saas", DARK_PRIMARY_STYLE), "dark")
|
||||
self.assertEqual(_resolve_color_mode("saas", DUAL_MODE_STYLE), "light")
|
||||
|
||||
|
||||
class TestPaletteSelection(unittest.TestCase):
|
||||
def test_dark_mode_skips_light_palettes(self):
|
||||
chosen = _select_palette_for_mode([LIGHT_PALETTE, DARK_PALETTE], "dark")
|
||||
self.assertEqual(chosen["Background"], "#0F172A")
|
||||
|
||||
def test_dark_mode_falls_back_to_top_hit_when_no_dark_ramp_exists(self):
|
||||
chosen = _select_palette_for_mode([LIGHT_PALETTE], "dark")
|
||||
self.assertEqual(chosen["Background"], "#F8FAFC")
|
||||
|
||||
def test_light_mode_keeps_the_existing_top_hit_behaviour(self):
|
||||
chosen = _select_palette_for_mode([DARK_PALETTE, LIGHT_PALETTE], "light")
|
||||
self.assertEqual(chosen["Background"], "#0F172A")
|
||||
|
||||
def test_empty_results(self):
|
||||
self.assertEqual(_select_palette_for_mode([], "dark"), {})
|
||||
|
||||
|
||||
class TestAntiPatternGating(unittest.TestCase):
|
||||
def test_dark_clause_dropped_others_kept(self):
|
||||
result = _filter_anti_patterns_for_mode(
|
||||
"Excessive animation + Dark mode by default", "dark")
|
||||
self.assertEqual(result, "Excessive animation")
|
||||
|
||||
def test_light_mode_is_a_no_op(self):
|
||||
original = "Excessive animation + Dark mode by default"
|
||||
self.assertEqual(_filter_anti_patterns_for_mode(original, "light"), original)
|
||||
|
||||
def test_unrelated_anti_patterns_survive_dark_mode(self):
|
||||
original = "Complex jargon + Tiny tap targets"
|
||||
self.assertEqual(_filter_anti_patterns_for_mode(original, "dark"), original)
|
||||
|
||||
def test_empty_input(self):
|
||||
self.assertEqual(_filter_anti_patterns_for_mode("", "dark"), "")
|
||||
|
||||
|
||||
class TestEndToEndCoherence(unittest.TestCase):
|
||||
"""The exact reproduction from issue #428."""
|
||||
|
||||
QUERY = "SaaS invoicing fintech B2B professional dark mode"
|
||||
|
||||
def test_dark_query_gets_a_dark_background(self):
|
||||
ds = DesignSystemGenerator().generate(self.QUERY)
|
||||
background = ds["colors"]["background"]
|
||||
self.assertTrue(
|
||||
_palette_is_dark({"Background": background}),
|
||||
"dark-mode query returned a light background: {}".format(background),
|
||||
)
|
||||
|
||||
def test_dark_query_foreground_is_lighter_than_background(self):
|
||||
ds = DesignSystemGenerator().generate(self.QUERY)
|
||||
background = _relative_luminance(ds["colors"]["background"])
|
||||
foreground = _relative_luminance(ds["colors"]["foreground"])
|
||||
self.assertIsNotNone(background)
|
||||
self.assertIsNotNone(foreground)
|
||||
self.assertGreater(foreground, background)
|
||||
|
||||
def test_dark_query_does_not_advise_against_dark_mode(self):
|
||||
ds = DesignSystemGenerator().generate(self.QUERY)
|
||||
self.assertNotIn("dark mode", ds["anti_patterns"].lower())
|
||||
|
||||
def test_light_query_keeps_a_light_background(self):
|
||||
ds = DesignSystemGenerator().generate("healthcare clinic booking app")
|
||||
self.assertFalse(_palette_is_dark({"Background": ds["colors"]["background"]}))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
# Uncle Bob Craft
|
||||
|
||||
Skill for applying Robert C. Martin (Uncle Bob) criteria to **code review and production**: Clean Code (with `@clean-code`), Clean Architecture, The Clean Coder, Clean Agile, code smells and heuristics, and design-pattern discipline.
|
||||
|
||||
## Contents
|
||||
|
||||
- **[SKILL.md](./SKILL.md)** — Main skill: when to use, overview, aggregators, design patterns, smells, review vs production, examples, related skills, limitations.
|
||||
- **[reference.md](./reference.md)** — Expanded reference: Clean Architecture, The Clean Coder, Clean Agile, smells/heuristics, design patterns, scope and attribution.
|
||||
- **[references/](./references/)** — Deep references: [clean-architecture.md](./references/clean-architecture.md), [clean-coder.md](./references/clean-coder.md), [clean-agile.md](./references/clean-agile.md), [design-patterns.md](./references/design-patterns.md).
|
||||
- **[examples/code-review-checklist.md](./examples/code-review-checklist.md)** — Copy-paste checklist for principle-based code review.
|
||||
|
||||
Use with `@uncle-bob-craft`. Complements `@clean-code`; does not replace the project linter or formatter.
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
---
|
||||
name: uncle-bob-craft
|
||||
description: "Use when performing code review, writing or refactoring code, or discussing architecture; complements clean-code and does not replace project linter/formatter."
|
||||
category: code-quality
|
||||
risk: safe
|
||||
source: community
|
||||
date_added: "2026-03-06"
|
||||
author: antigravity-contributors
|
||||
tags: [clean-code, clean-architecture, solid, code-review, craftsmanship, uncle-bob]
|
||||
tools: [claude, cursor, gemini]
|
||||
---
|
||||
|
||||
# Uncle Bob Craft
|
||||
|
||||
Apply Robert C. Martin (Uncle Bob) criteria for **code review and production**: Clean Code, Clean Architecture, The Clean Coder, Clean Agile, and design-pattern discipline. This skill is **complementary** to the existing `@clean-code` skill (which focuses on the Clean Code book) and to your project's linter/formatter—it does not replace them.
|
||||
|
||||
## Overview
|
||||
|
||||
This skill aggregates principles from Uncle Bob's body of work for **reviewing** and **writing** code: naming and functions (via `@clean-code`), architecture and boundaries (Clean Architecture), professionalism and estimation (The Clean Coder), agile values and practices (Clean Agile), and design-pattern use vs misuse. Use it to evaluate structure, dependencies, SOLID in context, code smells, and professional practices. It provides craft and design criteria only—not syntax or style enforcement, which remain the responsibility of your linter and formatter.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- **Code review**: Apply Dependency Rule, boundaries, SOLID, and smell heuristics; suggest concrete refactors.
|
||||
- **Refactoring**: Decide what to extract, where to draw boundaries, and whether a design pattern is justified.
|
||||
- **Architecture discussion**: Check layer boundaries, dependency direction, and separation of concerns.
|
||||
- **Design patterns**: Assess correct use vs cargo-cult or overuse before introducing a pattern.
|
||||
- **Estimation and professionalism**: Apply Clean Coder ideas (saying no, sustainable pace, three-point estimates).
|
||||
- **Agile practices**: Reference Clean Agile (Iron Cross, TDD, refactoring, pair programming) when discussing process.
|
||||
- **Do not use** to replace or override the project's linter, formatter, or automated tests.
|
||||
|
||||
## Aggregators by Source
|
||||
|
||||
| Source | Focus | Where to go |
|
||||
|--------|--------|-------------|
|
||||
| **Clean Code** | Names, functions, comments, formatting, tests, classes, smells | Use `@clean-code` for detail; this skill references it for review/production. |
|
||||
| **Clean Architecture** | Dependency Rule, layers, boundaries, SOLID in architecture | See [reference.md](./reference.md) and [references/clean-architecture.md](./references/clean-architecture.md). |
|
||||
| **The Clean Coder** | Professionalism, estimation, saying no, sustainable pace | See [reference.md](./reference.md) and [references/clean-coder.md](./references/clean-coder.md). |
|
||||
| **Clean Agile** | Values, Iron Cross, TDD, refactoring, pair programming | See [reference.md](./reference.md) and [references/clean-agile.md](./references/clean-agile.md). |
|
||||
| **Design patterns** | When to use, misuse, cargo cult | See [reference.md](./reference.md) and [references/design-patterns.md](./references/design-patterns.md). |
|
||||
|
||||
## Design Patterns: Use vs Misuse
|
||||
|
||||
- **Use patterns** when they solve a real design problem (e.g., variation in behavior, lifecycle, or cross-cutting concern), not to look "enterprise."
|
||||
- **Avoid cargo cult**: Do not add Factory/Strategy/Repository just because the codebase "should" have them; add them when duplication or rigidity justifies the abstraction.
|
||||
- **Signs of misuse**: Pattern name in every class name, layers that only delegate without logic, patterns that make simple code harder to follow.
|
||||
- **Rule of thumb**: Introduce a pattern when you feel the third duplication or the second reason to change; name the pattern in code or docs so intent is clear.
|
||||
|
||||
## Smells and Heuristics (Summary)
|
||||
|
||||
| Smell / Heuristic | Meaning |
|
||||
|-------------------|--------|
|
||||
| **Rigidity** | Small change forces many edits. |
|
||||
| **Fragility** | Changes break unrelated areas. |
|
||||
| **Immobility** | Hard to reuse in another context. |
|
||||
| **Viscosity** | Easy to hack, hard to do the right thing. |
|
||||
| **Needless complexity** | Speculative or unused abstraction. |
|
||||
| **Needless repetition** | DRY violated; same idea in multiple places. |
|
||||
| **Opacity** | Code is hard to understand. |
|
||||
|
||||
Full lists (including heuristics C1–T9-style) are in [reference.md](./reference.md). Use these in review to name issues and suggest refactors (extract, move dependency, introduce boundary).
|
||||
|
||||
## Review vs Production
|
||||
|
||||
| Context | Apply |
|
||||
|---------|--------|
|
||||
| **Code review** | Dependency Rule and boundaries; SOLID in context; list smells; suggest one or two concrete refactors (e.g., extract function, invert dependency); check tests and professionalism (tests present, no obvious pressure hacks). |
|
||||
| **Writing new code** | Prefer small functions and single responsibility; depend inward (Clean Architecture); write tests first when doing TDD; avoid patterns until duplication or variation justifies them. |
|
||||
| **Refactoring** | Identify one smell at a time; refactor in small steps with tests green; improve names and structure before adding behavior. |
|
||||
|
||||
## How It Works
|
||||
|
||||
### When reviewing code
|
||||
|
||||
1. **Boundaries and Dependency Rule**: Check that dependencies point inward (e.g., use cases do not depend on UI or DB details). See [references/clean-architecture.md](./references/clean-architecture.md).
|
||||
2. **SOLID in context**: Check Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion where they apply to the changed code.
|
||||
3. **Smells**: Scan for rigidity, fragility, immobility, viscosity, needless complexity/repetition, opacity; list them with file/area.
|
||||
4. **Concrete suggestions**: Propose one or two refactors (e.g., "Extract this into a function named X," "Introduce an interface so this layer does not depend on the concrete DB client").
|
||||
5. **Tests and craft**: Note if tests exist and if the change respects sustainable pace (no obvious "we'll fix it later" comments that violate professionalism).
|
||||
|
||||
### When writing or refactoring code
|
||||
|
||||
1. Prefer **small, single-purpose** functions and classes; use `@clean-code` for naming and structure.
|
||||
2. Keep **dependencies pointing inward**; put business rules in the center, adapters at the edges.
|
||||
3. Introduce **design patterns** only when duplication or variation justifies them.
|
||||
4. Refactor in **small steps** with tests staying green.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Code review prompt (copy-pasteable)
|
||||
|
||||
Use this to ask for an Uncle Bob–oriented review:
|
||||
|
||||
```markdown
|
||||
Please review this change using Uncle Bob craft criteria (@uncle-bob-craft):
|
||||
1. Dependency Rule and boundaries — do dependencies point inward?
|
||||
2. SOLID in context — any violations in the touched code?
|
||||
3. Smells — list rigidity, fragility, immobility, viscosity, needless complexity/repetition, or opacity.
|
||||
4. Suggest one or two concrete refactors (e.g., extract function, invert dependency).
|
||||
Do not duplicate lint/format; focus on structure and design.
|
||||
```
|
||||
|
||||
### Example 2: Before/after (extract and name)
|
||||
|
||||
**Before (opacity, does more than one thing):**
|
||||
|
||||
```python
|
||||
def process(d):
|
||||
if d.get("t") == 1:
|
||||
d["x"] = d["a"] * 1.1
|
||||
elif d.get("t") == 2:
|
||||
d["x"] = d["a"] * 1.2
|
||||
return d
|
||||
```
|
||||
|
||||
**After (clear intent, single level of abstraction):**
|
||||
|
||||
```python
|
||||
def apply_discount(amount: float, discount_type: int) -> float:
|
||||
if discount_type == 1:
|
||||
return amount * 1.1
|
||||
if discount_type == 2:
|
||||
return amount * 1.2
|
||||
return amount
|
||||
|
||||
def process(order: dict) -> dict:
|
||||
order["x"] = apply_discount(order["a"], order.get("t", 0))
|
||||
return order
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- ✅ Use `@clean-code` for naming, functions, comments, and formatting; use this skill for architecture, boundaries, SOLID, smells, and process.
|
||||
- ✅ In review, name the smell or principle (e.g., "Dependency Rule violation: use case imports from the web framework").
|
||||
- ✅ Suggest at least one concrete refactor per review (extract, rename, invert dependency).
|
||||
- ✅ Run the project linter and formatter separately; this skill does not replace them.
|
||||
- ❌ Do not use this skill to enforce syntax or style; that is the linter's job.
|
||||
- ❌ Do not add design patterns without a clear duplication or variation reason.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- **Problem:** Treating every class as needing a Factory or Strategy.
|
||||
**Solution:** Introduce patterns only when you have a real design need (third duplication, second axis of change).
|
||||
|
||||
- **Problem:** Review only listing "violates SOLID" without saying where or how.
|
||||
**Solution:** Point to the file/function and which principle (e.g., "SRP: this function parses and persists; split into parse and persist").
|
||||
|
||||
- **Problem:** Skipping the project linter because "we applied Uncle Bob."
|
||||
**Solution:** This skill is about craft and design; always run the project's lint and format.
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **`@clean-code`** — Detailed Clean Code book material (names, functions, comments, formatting, tests, classes, smells). Use for day-to-day code quality; use uncle-bob-craft for architecture and cross-book criteria.
|
||||
- **`@architecture`** — General architecture decisions and trade-offs. Use when choosing high-level structure; use uncle-bob-craft for Dependency Rule and boundaries.
|
||||
- **`@code-review-excellence`** — Code review practices. Combine with uncle-bob-craft for principle-based review.
|
||||
- **`@refactor-clean-code`** — Refactoring toward clean code. Use with uncle-bob-craft when refactoring for boundaries and SOLID.
|
||||
- **`@test-driven-development`** — TDD workflow. Aligns with Clean Agile and Clean Coder (tests as requirement, sustainable pace).
|
||||
|
||||
## Limitations
|
||||
|
||||
- **Does not replace the project linter or formatter.** Run lint and format separately; this skill gives design and craft criteria only.
|
||||
- **Does not replace automated tests.** It can remind you to write tests (Clean Coder, Clean Agile) but does not run or generate them.
|
||||
- **Complementary to tooling.** Use it alongside existing CI, lint, and test suites.
|
||||
- **No syntax or style enforcement.** It focuses on structure, dependencies, smells, and professional practice, not on brace style or line length.
|
||||
- **Summaries, not the books.** Full Clean Code heuristics, component principles (REP/CCP/CRP, ADP/SDP/SAP), and detailed stories are in the books; we reference the most used parts. See [reference.md](./reference.md) "Scope and attribution."
|
||||
@@ -1,55 +0,0 @@
|
||||
# Uncle Bob Craft — Code Review Checklist
|
||||
|
||||
Copy-paste this checklist when performing a principle-based code review with the uncle-bob-craft skill. Run your project linter/formatter separately; this checklist focuses on structure and design.
|
||||
|
||||
---
|
||||
|
||||
## 1. Dependency Rule and boundaries
|
||||
|
||||
- [ ] Dependencies point **inward** (use cases / domain do not depend on UI, DB, or framework details).
|
||||
- [ ] Outer layers depend on interfaces (e.g., repositories, gateways) defined by inner layers.
|
||||
- [ ] No direct import of framework or driver in the core/use-case code under review.
|
||||
|
||||
## 2. SOLID in context
|
||||
|
||||
- [ ] **SRP** — Each class/module has one reason to change (one actor).
|
||||
- [ ] **OCP** — Extension via new implementations, not by editing existing core logic.
|
||||
- [ ] **LSP** — Subtypes are substitutable; no hidden assumptions about concrete types.
|
||||
- [ ] **ISP** — Interfaces are focused; callers do not depend on methods they do not use.
|
||||
- [ ] **DIP** — High-level code depends on abstractions; concretions are injected at the edge.
|
||||
|
||||
## 3. Smells
|
||||
|
||||
- [ ] **Rigidity** — Small change does not force edits in many places.
|
||||
- [ ] **Fragility** — Change does not break unrelated areas.
|
||||
- [ ] **Immobility** — Reuse is possible where it makes sense.
|
||||
- [ ] **Viscosity** — Doing the right thing is not harder than hacking.
|
||||
- [ ] **Needless complexity** — No speculative or unused abstraction.
|
||||
- [ ] **Needless repetition** — DRY; no obvious duplication.
|
||||
- [ ] **Opacity** — Names and structure make intent clear.
|
||||
|
||||
## 4. Design patterns
|
||||
|
||||
- [ ] Any pattern used has a clear **reason** (duplication, variation, or boundary).
|
||||
- [ ] No cargo-cult pattern (e.g., Factory with a single implementation and no plan for variation).
|
||||
- [ ] Pattern improves readability or testability, not the opposite.
|
||||
|
||||
## 5. Tests and professionalism
|
||||
|
||||
- [ ] Touched code has or is covered by tests where appropriate.
|
||||
- [ ] No "we'll fix it later" or "TODO: refactor" that clearly violates sustainable pace or quality.
|
||||
- [ ] Commit/PR is coherent and does not leave the codebase worse.
|
||||
|
||||
---
|
||||
|
||||
## Suggested output format for review
|
||||
|
||||
1. **Boundaries**: One or two sentences on dependency direction and any violations.
|
||||
2. **SOLID**: List any violations with file/function and principle (e.g., "SRP: `OrderService` parses and persists — split.").
|
||||
3. **Smells**: List smells found with location (e.g., "Rigidity: changing discount rule touches 4 files.").
|
||||
4. **Concrete refactors**: One or two specific suggestions (e.g., "Extract `applyDiscount` from `process`"; "Introduce `OrderRepository` interface and inject in the use case.").
|
||||
5. **Tests / professionalism**: Brief note on test coverage and any concerns.
|
||||
|
||||
---
|
||||
|
||||
*Use with the skill: @uncle-bob-craft. For naming, functions, and formatting detail, also use @clean-code. Always run the project linter and formatter separately.*
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
# Uncle Bob Craft — Expanded Reference
|
||||
|
||||
This document expands the criteria referenced in the main skill. Sources: *Clean Code*, *Clean Architecture*, *The Clean Coder*, *Clean Agile* (Robert C. Martin). Use for progressive disclosure when you need full lists or deeper context.
|
||||
|
||||
---
|
||||
|
||||
## Clean Architecture
|
||||
|
||||
### Dependency Rule
|
||||
|
||||
Source code dependencies must point only **inward** (toward higher-level policies). Inner layers do not know about outer layers (e.g., use cases do not import from the web framework or the database driver).
|
||||
|
||||
- **Entities** (enterprise business rules) — center, no outward dependencies.
|
||||
- **Use cases** (application business rules) — depend only on entities.
|
||||
- **Interface adapters** (presenters, gateways) — depend on use cases/entities.
|
||||
- **Frameworks and drivers** (UI, DB, HTTP) — outermost; depend inward.
|
||||
|
||||
### Layers (hexagonal / ports and adapters)
|
||||
|
||||
| Layer | Responsibility | Depends on |
|
||||
|-------|----------------|------------|
|
||||
| Entities | Core business entities and rules | Nothing (innermost) |
|
||||
| Use cases | Application-specific business rules, orchestration | Entities |
|
||||
| Interface adapters | Convert data between use cases and external world | Use cases, entities |
|
||||
| Frameworks & drivers | DB, UI, HTTP, file I/O | Interface adapters |
|
||||
|
||||
### SOLID in architecture context
|
||||
|
||||
- **SRP** — A module should have one reason to change (one actor).
|
||||
- **OCP** — Open for extension, closed for modification (use abstractions and boundaries).
|
||||
- **LSP** — Subtypes must be substitutable for their base types (interfaces and implementations).
|
||||
- **ISP** — Many client-specific interfaces are better than one general-purpose interface (splitting interfaces at boundaries).
|
||||
- **DIP** — Depend on abstractions, not concretions (invert dependencies at boundaries).
|
||||
|
||||
### Component design (summary)
|
||||
|
||||
For grouping classes into components: **REP** (reuse/release equivalence), **CCP** (common closure), **CRP** (common reuse); **ADP** (acyclic dependencies), **SDP** (stable dependencies), **SAP** (stable abstractions). See [references/clean-architecture.md](./references/clean-architecture.md) for brief definitions.
|
||||
|
||||
---
|
||||
|
||||
## The Clean Coder
|
||||
|
||||
### Professionalism
|
||||
|
||||
- **Do no harm** — Do not leave the code worse than you found it; leave it better when you can.
|
||||
- **Work ethic** — Know your craft, practice, stay current.
|
||||
- **Saying no** — Say no when the request is unreasonable or would compromise quality; offer alternatives.
|
||||
- **Saying yes** — When you say yes, mean it; commit to deadlines you can meet.
|
||||
|
||||
### Estimation
|
||||
|
||||
- **Three-point estimates** — Best case, nominal, worst case; use for planning, not promises.
|
||||
- **Velocity** — Use historical velocity for iteration planning; do not inflate commitments.
|
||||
- **Uncertainty** — Communicate uncertainty; avoid false precision.
|
||||
|
||||
### Sustainable pace
|
||||
|
||||
- Avoid sustained overtime; it reduces quality and long-term output.
|
||||
- Tests and refactoring are part of the job, not "extra."
|
||||
|
||||
### Tests as requirement
|
||||
|
||||
- Code without tests is legacy by definition. Writing tests is a professional requirement.
|
||||
|
||||
### Mentoring and collaboration
|
||||
|
||||
- Helping others (mentoring, pairing) and leaving the team and codebase better are part of professionalism.
|
||||
|
||||
---
|
||||
|
||||
## Clean Agile
|
||||
|
||||
### Values (from Agile manifesto, emphasized by Uncle Bob)
|
||||
|
||||
- Individuals and interactions over processes and tools.
|
||||
- Working software over comprehensive documentation.
|
||||
- Customer collaboration over contract negotiation.
|
||||
- Responding to change over following a plan.
|
||||
|
||||
### Iron Cross (four values that support the above)
|
||||
|
||||
| Value | Meaning |
|
||||
|-------|--------|
|
||||
| **Communication** | Prefer face-to-face and collaboration; reduce information loss. |
|
||||
| **Courage** | Courage to refactor, to say no, to change design when needed. |
|
||||
| **Feedback** | Short feedback loops (tests, demos, iterations). |
|
||||
| **Simplicity** | Do the simplest thing that could work; avoid speculative design. |
|
||||
|
||||
### Practices
|
||||
|
||||
- **TDD** — Red, green, refactor; tests first as specification and safety net.
|
||||
- **Refactoring** — Continuous small improvements; keep tests green.
|
||||
- **Pair programming** — Two people at one machine; design and quality improve.
|
||||
- **Simple design** — No duplication, express intent, minimal elements, small abstractions.
|
||||
|
||||
---
|
||||
|
||||
## Smells and Heuristics (expanded)
|
||||
|
||||
### Design smells (from Clean Code / Clean Architecture)
|
||||
|
||||
| Code | Name | Brief |
|
||||
|------|------|--------|
|
||||
| **Rigidity** | Hard to change; one change triggers many. | Reduce coupling; introduce boundaries. |
|
||||
| **Fragility** | Breaks in unexpected places. | Isolate changes; improve tests. |
|
||||
| **Immobility** | Hard to reuse. | Extract reusable parts; reduce coupling. |
|
||||
| **Viscosity** | Easy to hack, hard to do right. | Make right thing easy (abstractions, tests). |
|
||||
| **Needless complexity** | Speculative or unused design. | YAGNI; remove until needed. |
|
||||
| **Needless repetition** | DRY violated. | Extract common logic; name the abstraction. |
|
||||
| **Opacity** | Hard to understand. | Rename, extract, clarify intent. |
|
||||
|
||||
### Heuristics (review checklist style)
|
||||
|
||||
- **C1 / Naming** — Names reveal intent; no disinformation (e.g., `accountList` when it is not a list).
|
||||
- **C2 / Functions** — Small, one thing, one level of abstraction; few arguments.
|
||||
- **C3 / Comments** — Prefer self-explanatory code; good comments for why, not what.
|
||||
- **C4 / Formatting** — Newspaper metaphor; vertical density; variables near use.
|
||||
- **C5 / Error handling** — Exceptions over return codes; don’t return or pass null without contract.
|
||||
- **C6 / Tests** — F.I.R.S.T.; TDD when applicable.
|
||||
- **C7 / Classes** — Small, single responsibility; stepdown rule.
|
||||
- **T1 / Boundaries** — Dependencies point inward; no outer details in inner layers.
|
||||
- **T2 / SOLID** — Check SRP, OCP, LSP, ISP, DIP in context.
|
||||
- **T3 / Patterns** — Pattern used to solve a real problem, not for show.
|
||||
|
||||
(You can extend to a full C1–T9 list in your team; the above is a compact reference.)
|
||||
|
||||
---
|
||||
|
||||
## Design patterns (when and when not)
|
||||
|
||||
- **Use** when: you have repeated variation (Strategy), lifecycle/creation complexity (Factory), or a clear cross-cutting concern (e.g., logging, validation at a boundary).
|
||||
- **Avoid** when: the code is simple and a pattern would add indirection without reducing duplication or clarifying intent.
|
||||
- **Cargo cult** — Applying a pattern by name everywhere (e.g., everything is a Factory) without a design reason. Prefer "simplest thing that could work" until duplication or change axis appears.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Scope and attribution
|
||||
|
||||
- **Clean Code** — Full heuristics and chapter-by-chapter detail: use the `@clean-code` skill. This skill references Clean Code for review context and defers naming/functions/formatting there.
|
||||
- **Clean Architecture** — We cover the Dependency Rule, layers, boundaries, SOLID in architecture, and component cohesion/coupling (REP, CCP, CRP, ADP, SDP, SAP) in summary; the book has full treatment and more nuance.
|
||||
- **The Clean Coder** — We summarize professionalism, estimation, sustainable pace, tests, and mentoring; the book has full chapters and stories.
|
||||
- **Clean Agile** — We summarize values, Iron Cross, and key practices (TDD, refactoring, pairing, simple design); the book ties them to agile history and adoption.
|
||||
|
||||
*Attribution: Principles and structure drawn from Robert C. Martin, Clean Code (2008), Clean Architecture (2017), The Clean Coder (2011), Clean Agile (2019). This reference is a summary for agent use, not a substitute for the books.*
|
||||
@@ -1,32 +0,0 @@
|
||||
# Clean Agile — Deep Reference
|
||||
|
||||
Based on Robert C. Martin, *Clean Agile* (2019). Use this when discussing agile values, practices, and the "Iron Cross."
|
||||
|
||||
## Agile values (manifesto)
|
||||
|
||||
- Individuals and interactions over processes and tools.
|
||||
- Working software over comprehensive documentation.
|
||||
- Customer collaboration over contract negotiation.
|
||||
- Responding to change over following a plan.
|
||||
|
||||
Uncle Bob stresses that the right-hand side still has value; the left-hand side is preferred when there is a trade-off.
|
||||
|
||||
## Iron Cross (four supporting values)
|
||||
|
||||
| Value | What it means in practice |
|
||||
|-------|---------------------------|
|
||||
| **Communication** | Prefer face-to-face (or high-bandwidth) communication; reduce information loss; keep the team aligned. |
|
||||
| **Courage** | Courage to refactor, to say no to unreasonable requests, to change the design when the code tells you to. |
|
||||
| **Feedback** | Short feedback loops—unit tests, integration tests, demos, small iterations. Learn fast what works and what doesn’t. |
|
||||
| **Simplicity** | Do the simplest thing that could possibly work. Avoid speculative design and unnecessary abstraction. |
|
||||
|
||||
## Practices
|
||||
|
||||
- **TDD (Test-Driven Development)** — Red, green, refactor. Write a failing test first, then minimal code to pass, then refactor. Tests act as specification and safety net.
|
||||
- **Refactoring** — Continuous small improvements. Keep tests green; improve structure, names, and design in small steps.
|
||||
- **Pair programming** — Two people at one machine. Improves design and quality; spreads knowledge. Not mandatory every hour, but a recognized practice for hard or critical work.
|
||||
- **Simple design** — No duplication; express intent; minimal elements (classes, methods); small, focused abstractions. Add complexity only when the code asks for it (e.g., third duplication).
|
||||
|
||||
## Relationship to craft
|
||||
|
||||
Clean Agile ties agile values to craft: sustainable pace, tests as requirement, refactoring as part of the loop, and simplicity over speculation. Use this reference when discussing how TDD, refactoring, or pairing support agility and quality.
|
||||
@@ -1,56 +0,0 @@
|
||||
# Clean Architecture — Deep Reference
|
||||
|
||||
Based on Robert C. Martin, *Clean Architecture* (2017). Use this when you need detailed criteria for dependency direction, layers, and boundaries.
|
||||
|
||||
## Dependency Rule
|
||||
|
||||
**Dependencies point inward only.** Code in the center (entities, use cases) must not depend on code in outer circles (UI, DB, frameworks). Outer circles depend on inner circles; inner circles define interfaces, outer circles implement them.
|
||||
|
||||
- **Violation**: A use case that imports from Express, Django, or a concrete repository implementation.
|
||||
- **Correct**: Use case depends on an interface (e.g., `OrderRepository`); the adapter in the outer layer implements it and uses Express/DB.
|
||||
|
||||
## Layers (from inside out)
|
||||
|
||||
1. **Entities** — Enterprise business rules. Plain structures and rules that apply across the application. No dependencies on frameworks or UI.
|
||||
2. **Use cases** — Application business rules. Orchestrate entities and define application-specific workflows. Depend only on entities and on interfaces for I/O (repositories, presenters).
|
||||
3. **Interface adapters** — Convert data between use cases and the outside world. Presenters, gateways, controllers that translate external format to/from use-case format. Depend on use cases (and entities only via use cases).
|
||||
4. **Frameworks and drivers** — Web framework, DB driver, messaging, file I/O. Implement interfaces defined by use cases or interface adapters. Depend inward.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- **Boundary** = interface or abstract type that inner code depends on; outer code implements.
|
||||
- Good boundaries make it easy to swap implementations (e.g., in-memory repo for tests, SQL repo for production).
|
||||
- Draw boundaries where there is a reason to vary or replace (different persistence, different UI, different transport).
|
||||
|
||||
## SOLID in this context
|
||||
|
||||
- **SRP** — Each module (class/package) has one reason to change (one actor). E.g., separate "report formatting" from "report calculation" if they change for different reasons.
|
||||
- **OCP** — Extend behavior via new implementations of interfaces (new adapters), not by editing existing use-case or entity code.
|
||||
- **LSP** — Any implementation of a repository or gateway interface must be substitutable without breaking the use case.
|
||||
- **ISP** — Small, focused interfaces (e.g., `ReadOrderRepository` and `WriteOrderRepository` if read and write evolve differently) instead of one fat `OrderRepository`.
|
||||
- **DIP** — Use cases depend on `OrderRepository` (interface); the composition root wires in `SqlOrderRepository`. High-level policy does not depend on low-level details.
|
||||
|
||||
## Inversion of dependencies
|
||||
|
||||
- **Without inversion**: Use case imports and calls `SqlOrderRepository` directly → use case depends on DB.
|
||||
- **With inversion**: Use case depends on `OrderRepository` (interface); `SqlOrderRepository` implements it and is injected at the edge. Use case stays independent of SQL.
|
||||
|
||||
## Component cohesion and coupling (for larger systems)
|
||||
|
||||
When grouping classes into **components** (modules, packages), Uncle Bob defines:
|
||||
|
||||
**Cohesion:**
|
||||
- **REP (Reuse/Release Equivalence)** — The unit of reuse is the unit of release; group classes that are reused and released together.
|
||||
- **CCP (Common Closure)** — Classes that change for the same reasons belong in the same component; reduces impact of change.
|
||||
- **CRP (Common Reuse)** — Classes reused together should be packaged together; avoid forcing dependents to pull in more than they need.
|
||||
|
||||
**Coupling:**
|
||||
- **ADP (Acyclic Dependencies)** — Component dependency graph must have no cycles.
|
||||
- **SDP (Stable Dependencies)** — Depend in the direction of stability; less stable components depend on more stable ones.
|
||||
- **SAP (Stable Abstractions)** — Stable components should be abstract; unstable components can be concrete.
|
||||
|
||||
Use this when discussing module/package boundaries beyond single layers. For full treatment see *Clean Architecture* (Martin, 2017).
|
||||
|
||||
---
|
||||
|
||||
Use this reference when reviewing for "dependency direction," "layer violations," or "missing boundaries."
|
||||
@@ -1,34 +0,0 @@
|
||||
# The Clean Coder — Deep Reference
|
||||
|
||||
Based on Robert C. Martin, *The Clean Coder* (2011). Use this when discussing professionalism, estimation, and sustainable pace.
|
||||
|
||||
## Professionalism
|
||||
|
||||
- **Do no harm** — Do not leave the codebase in a worse state. If you must leave a mess, leave a clear TODO and track it. Prefer leaving code better than you found it (boy scout rule).
|
||||
- **Know your craft** — Practice (e.g., katas), read, stay current. Estimate only what you understand enough to estimate.
|
||||
- **Saying no** — When a request would compromise quality or is unreasonable, say no. Offer alternatives (e.g., "We can do X by date Y if we drop Z" or "We need two more weeks for tests").
|
||||
- **Saying yes** — When you commit, mean it. Do not say yes to please and then miss; communicate early if you cannot meet a commitment.
|
||||
|
||||
## Estimation
|
||||
|
||||
- **Three-point estimate** — Best / nominal / worst case. Use for planning and risk, not as a single "promise" number.
|
||||
- **Velocity** — Use historical velocity for iteration planning. Do not inflate; if the team goes fast once, use that as data for the next time, not as the new permanent commitment.
|
||||
- **Uncertainty** — Make uncertainty visible. Prefer ranges and confidence levels over false precision.
|
||||
- **Refusal to estimate** — It is professional to refuse to give a date when the request is vague or the work is unknown; offer to break it down first or to give a range after discovery.
|
||||
|
||||
## Sustainable pace
|
||||
|
||||
- Sustained overtime reduces quality and long-term output. Occasional crunch may happen; make it rare and recover afterward.
|
||||
- Tests, refactoring, and learning are part of the job. Skipping them to "hit the date" creates technical debt and is unprofessional in the long run.
|
||||
|
||||
## Tests as a requirement
|
||||
|
||||
- Code without tests is legacy. Writing and maintaining tests is part of professional delivery, not optional.
|
||||
- When under pressure, the first thing to protect is the test suite and the ability to refactor safely.
|
||||
|
||||
## Mentoring and collaboration
|
||||
|
||||
- **Helping others** — Part of professionalism is mentoring, pairing, and leaving the codebase (and the team) better than you found it.
|
||||
- **Collaboration** — Communicate clearly with stakeholders and peers; say no when needed, and offer alternatives when saying yes is not possible.
|
||||
|
||||
Use this reference when the discussion involves commitment, estimates, saying no, sustainable development practices, or teamwork.
|
||||
@@ -1,32 +0,0 @@
|
||||
# Design Patterns — Use vs Misuse
|
||||
|
||||
Use this when evaluating whether a design pattern is justified or is cargo cult / overuse.
|
||||
|
||||
## When to use a pattern
|
||||
|
||||
- **Repeated variation** — Same algorithm or structure with different behavior (e.g., different discount rules) → Strategy or similar.
|
||||
- **Lifecycle or creation complexity** — Object creation has many variants or steps → Factory, Builder when the duplication or complexity is real.
|
||||
- **Cross-cutting concern** — Logging, validation, auth at a boundary → Decorator, middleware, or adapter at the edge.
|
||||
- **Stable abstraction, varying implementation** — You expect to swap implementations (e.g., repository, gateway) → Interface + implementations; dependency injection.
|
||||
|
||||
Rule of thumb: introduce a pattern when you feel the **third duplication** or the **second axis of change** (second reason to open the same module). Name the pattern in code or docs so intent is clear.
|
||||
|
||||
## When not to use a pattern
|
||||
|
||||
- **Simple, linear code** — No duplication, one reason to change. Adding a Factory or Strategy here adds indirection without benefit.
|
||||
- **Speculative need** — "We might need to swap implementations later." Prefer YAGNI; add the abstraction when you actually have a second implementation or a second reason to change.
|
||||
- **Every class is a pattern** — Not every class needs to be behind a Factory or an Interface. Use patterns where they solve a real design problem.
|
||||
|
||||
## Cargo cult and misuse
|
||||
|
||||
- **Cargo cult** — Using a pattern because "that’s what we do" or "enterprise code has Factories," without a clear design reason. Symptoms: Factory that only calls `new`, Strategy with one implementation and no plan for a second.
|
||||
- **Overuse** — Pattern names in every class name; layers that only delegate and add no logic; code that is harder to follow than a straightforward version.
|
||||
- **Misuse** — Wrong pattern for the problem (e.g., Singleton for something that should be testable and replaceable); pattern that hides the real design (e.g., God Object behind a Facade).
|
||||
|
||||
## Good signals
|
||||
|
||||
- The pattern name appears in design docs or comments where it helps (e.g., "Strategy for discount calculation").
|
||||
- There are at least two concrete variants or a clear, stated reason for future variation.
|
||||
- Tests and call sites are simpler because of the abstraction (e.g., tests inject a fake repository).
|
||||
|
||||
Use this reference in review when someone proposes or has added a Factory, Strategy, Repository, or other pattern—ask "what duplication or variation does this solve?" and "is there a second implementation or a second reason to change?"
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: wait-what
|
||||
description: Stop. That last message did not land — re-pitch it.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Wait — I don't understand where you've got to here. Re-pitch that: give me a little bit of context, talk in ASD-STE100 Simplified Technical English, and use the ubiquitous language from `CONTEXT.md`.
|
||||
@@ -1,5 +0,0 @@
|
||||
interface:
|
||||
display_name: "Wait What"
|
||||
short_description: "Re-pitch that — simpler, with the context I'm missing"
|
||||
policy:
|
||||
allow_implicit_invocation: false
|
||||
@@ -1,22 +0,0 @@
|
||||
# Skill mechanics
|
||||
|
||||
The skill-specific branch of [`writing-for-agents`](SKILL.md): what changes when the document is a skill — frontmatter, the invocation choice, and router skills. Everything else about writing it is the universal reference in `SKILL.md`.
|
||||
|
||||
## Invocation
|
||||
|
||||
Two choices, trading the two loads:
|
||||
|
||||
- A **model-invoked** skill keeps a `description`, so the agent can fire it autonomously — and other skills can reach it. You can still type its name: model-invocation always _includes_ user reach; a description only ever adds agent discovery, never removes the human's. The description is the skill's top-level context pointer, forced to stay loaded at all times — permanent context load in exchange for discoverability. A model-invoked skill whose content is all reference is also one home for shared reference: another skill can invoke it, so reference needed by several skills lives in one place. Mechanics: omit `disable-model-invocation`, and write a model-facing description carrying the trigger branches (the pointer-writing rules in `SKILL.md` apply in full).
|
||||
- A **user-invoked** skill strips the description from the agent's reach: only the human typing its name can invoke it, and no other skill can. Zero context load, but it spends cognitive load — you are the index that must remember it exists. Mechanics: set `disable-model-invocation: true`; the `description` becomes human-facing — a one-line summary, trigger lists stripped.
|
||||
|
||||
Pick model-invocation only when the agent must reach the skill on its own, or another skill must. If it only ever fires by hand, make it user-invoked and pay no context load.
|
||||
|
||||
Shared reference that two user-invoked skills both need can live in neither — with no descriptions, neither can fire the other. Push it to a plain file outside the skill system: external reference any skill can point at.
|
||||
|
||||
## Splitting by invocation
|
||||
|
||||
The invocation cut of splitting (the sequence cut lives in `SKILL.md`): split off a model-invoked skill when you have a distinct leading word that should trigger it on its own — a trigger word you actually use in your prompts — or another skill must reach it. You pay context load for the new always-loaded description, so that independent reach has to be worth it.
|
||||
|
||||
## Router skills
|
||||
|
||||
When user-invoked skills multiply past what you can remember, that piled-up cognitive load is cured by a **router skill**: one user-invoked skill that names the others and when to reach for each, so the human has one skill to remember instead of many. It can only hint, never fire them: user-invoked skills have no description, so nothing but the human can reach them.
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
---
|
||||
name: writing-for-agents
|
||||
description: Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.
|
||||
---
|
||||
|
||||
Reference for writing any document an agent consumes — a skill, an `AGENTS.md` / `CLAUDE.md`, a doc reached by a pointer. The packaging differs; the writing does not: the same levers make each one predictable — the agent taking the same _process_ every run, not producing the same output.
|
||||
|
||||
When the document you're writing is a skill, read [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md) for frontmatter, invocation choice, and router skills.
|
||||
|
||||
## Context pointers
|
||||
|
||||
A **context pointer** is a reference held in the agent's context that names some out-of-context material and encodes the condition for reaching it. A skill's description is one; a line in `AGENTS.md` naming a doc is the same object. The pointer's _wording_, not its target, decides when the agent reaches the material — and how reliably. A must-have target behind a weakly worded pointer is a variance bug: sharpen the wording first, and inline the material only if sharpening fails.
|
||||
|
||||
A pointer does two jobs — state what the material is, and list the **branches** that should trigger reaching it (a branch is a distinct case the document handles, so different runs take different paths through it). Every word of an always-loaded pointer costs on every turn, so it earns even harder pruning than the body:
|
||||
|
||||
- **Front-load the leading word** — the pointer is where it does its triggering work.
|
||||
- **One trigger per branch.** Synonyms that rename a single branch are one branch written twice; collapse them and keep only genuinely distinct branches.
|
||||
- **Cut identity the body already carries.**
|
||||
|
||||
## The two loads
|
||||
|
||||
Every document and pointer you add spends one of two budgets:
|
||||
|
||||
- **Context load** — the cost of always-loaded material on the agent's window: an `AGENTS.md` line, a skill description, anything sitting in context every turn, spending tokens and attention whether or not it fires.
|
||||
- **Cognitive load** — the cost on the human: which documents exist and when to reach for each. The human is the index. Not a cost to minimise — it is the price of human agency; spend it where human judgement matters, remove it where it does not.
|
||||
|
||||
Material reached only through a pointer escapes context load at the price of the pointer's own line; material with no pointer at all rides entirely on cognitive load.
|
||||
|
||||
## Information hierarchy
|
||||
|
||||
A document is built from two content types — **steps** (the ordered actions the agent performs) and **reference** (definitions, rules, facts consulted on demand) — that mix freely: all steps (a recipe), all reference (a review's rules, this skill), or both. The core decision is where each piece sits on the **information hierarchy**, a ladder ranked by how immediately the agent needs the material:
|
||||
|
||||
1. **In-file step** — the primary tier: what the agent does, in order.
|
||||
2. **In-file reference** — consulted on demand. Often a legitimately flat peer-set (every rule of a review on one rung) — a fine arrangement, not a smell.
|
||||
3. **Disclosed reference** — pushed out into a separate file, reached by a context pointer, loaded only when the pointer fires. Spans a sibling file in the same folder through fully external reference that lives anywhere and any document can point at.
|
||||
|
||||
Push too little down and the top bloats; push too much and you hide material the agent actually needs. That tension is the whole decision.
|
||||
|
||||
**Progressive disclosure** is the move down the ladder — out of the main file and behind a pointer — so the top stays legible. Not primarily a token optimisation: it is how the hierarchy is protected. Branching is the cleanest disclosure test: inline what every branch needs, and push behind a pointer what only some branches reach. When a document has steps, in-file reference that should be disclosed buries them and turns attending to them into a coin-flip — a variance lever, not just a legibility one.
|
||||
|
||||
**Co-location** is the within-file companion: where the ladder decides _how far down_ a piece sits, co-location decides _what sits beside it_ once there. Keep a concept's definition, rules, and caveats under one heading rather than scattered, so reading one part brings its neighbours with it. The test: the document should read like documentation written for the agent — grouped material reads that way; scattered material does not. (Distinct from duplication: that repeats one meaning in two places; scattering fragments one meaning across many.)
|
||||
|
||||
**Sprawl** is the failure mode here: a document simply too long, even when every line is live and unique. Attention thins across the excess, and every extra line is one more to keep relevant. The cure is the ladder: disclose reference behind pointers, and split by branch or sequence so each path carries only what it needs.
|
||||
|
||||
## Steps and completion criteria
|
||||
|
||||
Every step ends on a **completion criterion** — the condition that tells the agent the work is done. Two properties make it a lever:
|
||||
|
||||
- **Clarity** — can the agent tell done from not-done? A vague bound ("understanding reached") invites **premature completion**: ending the step before it is genuinely done, attention slipping to _being done_. The visible steps still ahead — the **post-completion steps** — supply the pull; the criterion's clarity is the resistance. Defend in order: **sharpen the bound first** (local and cheap); only if it is irreducibly fuzzy _and_ you observe the rush, hide the later steps by splitting the sequence — and hiding only works across a real context boundary (a hand-off or a subagent dispatch; an inline call leaves the later steps in context and clears nothing).
|
||||
- **Demand** — how much it requires. "Every modified model accounted for" forces thorough work where "produce a change list" does not. Demand drives **legwork** — the digging the agent does within the work, latent in the wording rather than written as its own step — and it is not step-bound: "every rule applied" binds a body of flat reference just as "every step done" binds a sequence, which is how an all-reference document still carries an exhaustiveness bar.
|
||||
|
||||
The strongest criteria are both checkable and exhaustive.
|
||||
|
||||
## When to split
|
||||
|
||||
Splitting one document into two spends one of the two loads, so split only when the cut earns it:
|
||||
|
||||
- **By sequence** — split a run of steps where the post-completion steps tempt the agent to rush the one in front of it. Keeping them out of view drives more legwork on the current task. Beware the reverse: merging sequences exposes each step's later steps to what follows, inviting premature completion.
|
||||
- **By invocation** — skill-specific: see [`SKILL-MECHANICS.md`](SKILL-MECHANICS.md).
|
||||
|
||||
## Leading words
|
||||
|
||||
A **leading word** is a compact concept already living in the model's pretraining that the agent thinks with while running the document (_lesson_, _fog of war_, _tracer bullets_). Repeated as a token, never as a sentence, it accumulates a distributed definition and anchors a whole region of behaviour in the fewest tokens, by recruiting priors the model already holds. Coining your own works if you define it clearly, but a made-up word recruits no priors — you pay in definition tokens what a pretrained word gives free; reach for an existing word first.
|
||||
|
||||
It anchors twice. In the body, _execution_: the agent reaches for the same behaviour every time the word appears, and inside flat reference it focuses attention on a class of thing to look for. In a pointer, _invocation_: when the same word lives in your prompts, your docs, and your codebase, the agent links that shared language to the material and reaches it more reliably.
|
||||
|
||||
Hunt for opportunities to refactor with leading words. A triad spelled out at three sites, a pointer spending a sentence to gesture at one idea — each is a passage begging to collapse into a single token:
|
||||
|
||||
- "fast, deterministic, low-overhead" → _tight_ (a _tight_ loop).
|
||||
- "a loop you believe in" → _red_ — a fuzzy gate becomes a binary observable state (the loop goes _red_ on the bug, or it doesn't).
|
||||
|
||||
You win twice: fewer tokens, and a sharper hook for the agent to hang its thinking on. Assume every document is carrying restatements that leading words retire — go find them.
|
||||
|
||||
**Negation** is the failure mode beside this lever: steering by prohibition drags the forbidden behaviour into context and makes it _more_ available, not less. _Don't think of an elephant_, and the elephant is all there is; the negation is a weak modifier the strongly-activated concept overruns, so the ban half-reads as an instruction to do the thing. Prompt the **positive** — state the target behaviour ("write one-line comments") so the banned one is never spoken. A prohibition earns its place only as a hard guardrail you cannot phrase positively; even then, pair it with the positive target so attention lands on what to do.
|
||||
|
||||
## Pruning
|
||||
|
||||
- Keep each meaning in a **single source of truth**: one authoritative place, so changing the behaviour is a one-place edit. **Duplication** — the same meaning in more than one place — costs maintenance and tokens, and inflates a meaning's prominence on the ladder past its real rank. (The accidental inverse of a leading word, which repeats a token on purpose, never the meaning.)
|
||||
- The **environment** is a source of truth too — `package.json` scripts, config files, the directory layout, `--help` output — and a document that restates it is a **cache**: a copy of a lookup, earning its load only when the lookup is expensive. Cache what the agent cannot find by looking: the unwritten convention, the reason behind a choice, the gotcha no config confesses. Leave the one-file, one-command lookups to the environment, where they cannot go stale.
|
||||
- Check every line for **relevance**: does it still bear on what the document does? A line loses relevance by never bearing on the task (mere exposition, or a branch that should be disclosed) or by going stale as the behaviour or world it describes changes. Shorter documents are easier to keep relevant. Without a pruning discipline the default fate is **sediment**: stale layers that settle because adding feels safe and removing feels risky, until you must core down through them to find what is still live.
|
||||
- Hunt **no-ops** sentence by sentence: an instruction the model already obeys by default pays load to say nothing. The test — does it change behaviour versus the default? — is model-relative, not reader-relative: two people disagreeing about a no-op disagree about the default, and settle it by running the document, not by debate. When a sentence fails, delete the whole sentence rather than trim words from it. The test also grades leading words: a word too weak to beat the default (_be thorough_ when the agent is already thorough-ish) is a no-op, and the fix is a stronger word (_relentless_), not a different technique.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user