Skip to content

Commit ddd4f30

Browse files
Ssandor13claude
andcommitted
feat: adds a skill to scaffold new ECCs
Adds a local Claude Code skill (`.claude/skills/create-ecc/SKILL.md`) that scaffolds a new composable characteristic as a schema-valid YAML file, mirroring the data model in `crates/ecc/src/`. Documents the skill in the README and adds MYCN amplification as ECC-MOLEC-000002 (binary: amplified vs not). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ffb8ac0 commit ddd4f30

2 files changed

Lines changed: 193 additions & 0 deletions

File tree

.claude/skills/create-ecc/SKILL.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
name: create-ecc
3+
description: Scaffold a new ECC (composable characteristic) as a schema-valid YAML file under ecc/morph or ecc/molec. Use when asked to add, create, or draft a new composable characteristic / ECC, or a new morphological or molecular characteristic. Produces a file that passes `cargo run -p ecc-cli -- check ecc`.
4+
---
5+
6+
# Create an ECC (composable characteristic)
7+
8+
Scaffold a new composable characteristic as a YAML file that deserializes cleanly
9+
into the `ecc::Characteristic` model. The authoritative schema lives in
10+
`crates/ecc/src/` — this skill mirrors it. If in doubt, read `crates/ecc/src/lib.rs`,
11+
`crates/ecc/src/common.rs`, `crates/ecc/src/common/value/kind.rs`, and
12+
`crates/ecc/src/identifier.rs` before writing.
13+
14+
## 1. Pick the type, number, and identifier
15+
16+
Each ECC lives in one of two folders, and its identifier type must match:
17+
18+
| Type | Folder | Identifier prefix | Rust variant |
19+
| ------------- | ------------ | ----------------- | ------------------------ |
20+
| Morphological | `ecc/morph/` | `ECC-MORPH-` | `Identifier::Morphological` |
21+
| Molecular | `ecc/molec/` | `ECC-MOLEC-` | `Identifier::Molecular` |
22+
23+
- **Identifier format**: `ECC-{MORPH|MOLEC}-NNNNNN` — prefix and type are
24+
UPPERCASE, and the number is exactly **6 zero-padded digits**, starting at
25+
`000001` (zero is invalid). Example: `ECC-MOLEC-000002`.
26+
- **Filename**: `NNNNNN-kebab-case-name.yml` in the matching folder, using the
27+
**same 6-digit number** as the identifier. Keep the filename number and the
28+
identifier number in sync. Example: `ecc/molec/000002-mycn-amplification.yml`.
29+
- Choose the next unused number by listing the target folder (e.g. `ls ecc/molec`).
30+
31+
## 2. Choose the `state` and its required fields
32+
33+
`state` is the enum tag (`crates/ecc/src/lib.rs`, `#[serde(tag = "state")]`,
34+
`deny_unknown_fields` — so **no extra/unknown keys** are allowed). The state
35+
determines which fields are required:
36+
37+
| `state` | Required fields |
38+
| ------------- | --------------------------------------------------------------------- |
39+
| `draft` | none — every common field is optional (use while still filling it in) |
40+
| `proposed` | all common fields |
41+
| `provisional` | all common fields |
42+
| `adopted` | all common fields **plus** `adoption_date` (RFC 3339 timestamp) |
43+
44+
**Common fields** (from `crates/ecc/src/common.rs`), required for
45+
proposed/provisional/adopted:
46+
47+
- `name` — string, human-readable title.
48+
- `identifier` — the `ECC-…` identifier string (see step 1).
49+
- `rfc` — a GitHub issue URL that MUST match
50+
`https://github.com/stjudecloud/ecc/issues/<number>` (enforced by regex in
51+
`crates/ecc/src/rfc.rs`).
52+
- `description` — string; may be Markdown (block scalar `|` recommended).
53+
- `values` — the value kind (see step 3).
54+
- `references` — optional list; if present it must be **non-empty** (see step 4).
55+
56+
## 3. Define `values` (the value kind)
57+
58+
`values.kind` is the enum tag (`crates/ecc/src/common/value/kind.rs`,
59+
`#[serde(tag = "kind")]`). One of:
60+
61+
- **`binary`** — a true/false determination (e.g. present/absent,
62+
amplified/not amplified). Requires a `description` with a `"true"` and a
63+
`"false"` entry, each an object with `summary` and `details`. **Quote the
64+
`"true"`/`"false"` keys** so YAML does not parse them as booleans. `summary`
65+
and `details` are sentences and must be non-empty.
66+
67+
```yaml
68+
values:
69+
kind: binary
70+
description:
71+
"true":
72+
summary: A one-line summary of the true case.
73+
details: |
74+
A longer explanation of what "true" means for this characteristic.
75+
"false":
76+
summary: A one-line summary of the false case.
77+
details: |
78+
A longer explanation of what "false" means for this characteristic.
79+
```
80+
81+
- **`categorical`** — a fixed set of string options:
82+
83+
```yaml
84+
values:
85+
kind: categorical
86+
options:
87+
- Option A
88+
- Option B
89+
```
90+
91+
- **`numerical`** — a measured number with a type and units. `type` is one of
92+
`signed`, `unsigned`, or `float`:
93+
94+
```yaml
95+
values:
96+
kind: numerical
97+
type: float
98+
units: percent
99+
```
100+
101+
## 4. Optional `references`
102+
103+
If included, `references` is a non-empty list. Each entry has a `kind` of
104+
`manuscript` or `preprint` (`crates/ecc/src/common/reference.rs`) with:
105+
`title` (string), `authors` (string), `context` (a non-empty sentence),
106+
`url` (any valid URL), and `highlighted` (bool). Omit the whole `references`
107+
key if you have none — do not write an empty list.
108+
109+
```yaml
110+
references:
111+
- kind: manuscript
112+
title: The title of the paper.
113+
authors: A. Author, B. Author
114+
context: One sentence on why this paper is relevant to this ECC.
115+
url: https://pubmed.ncbi.nlm.nih.gov/123456
116+
highlighted: true
117+
```
118+
119+
## 5. Full template (proposed, binary)
120+
121+
```yaml
122+
state: proposed
123+
name: <Human Readable Name>
124+
identifier: ECC-MOLEC-NNNNNN
125+
rfc: https://github.com/stjudecloud/ecc/issues/<n>
126+
description: |
127+
# Overview
128+
129+
A Markdown description of the characteristic.
130+
values:
131+
kind: binary
132+
description:
133+
"true":
134+
summary: <summary of the true case>.
135+
details: |
136+
<details of the true case>
137+
"false":
138+
summary: <summary of the false case>.
139+
details: |
140+
<details of the false case>
141+
```
142+
143+
`ecc/000000-example.yml` is a complete, valid reference example.
144+
145+
## 6. Validate
146+
147+
Always validate after writing the file. The checker globs `ecc/**/*.yml` and
148+
deserializes each into `Characteristic`, printing `OK` or `FAIL`. The Cargo
149+
workspace lives in `crates/`, so run it from the repo root with an explicit
150+
manifest path (this matches CI's `ecc-cli check ecc`, which installs the binary
151+
first and runs from the root):
152+
153+
```bash
154+
cargo run --manifest-path crates/Cargo.toml -p ecc-cli -- check ecc
155+
```
156+
157+
If a file `FAIL`s, read the diagnostic (it points at the offending location),
158+
compare against the schema above, and fix — common causes: unquoted
159+
`true`/`false` keys, wrong identifier padding or type, an `rfc` URL that is not a
160+
`stjudecloud/ecc` issue, unknown/extra keys (`deny_unknown_fields`), or an empty
161+
`references` list.

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,38 @@ cargo build --release
2020
cargo run --release --example
2121
```
2222

23+
## 🤖 Authoring characteristics with Claude
24+
25+
This repository ships a [Claude Code][claude-code] skill, `create-ecc`, that
26+
guides an agent through **researching and authoring** a new composable
27+
characteristic — not just writing YAML, but producing an evidence-backed entry a domain expert would sign off on. It lives at `.claude/skills/create-ecc/SKILL.md` and is discovered automatically by any agent started in this repository.
28+
29+
### What it does
30+
31+
1. **Research first.** Before writing anything, the agent builds an evidence
32+
brief: a precise definition and scope, the correct category (`morph` vs
33+
`molec`), primary-literature citations with resolvable URLs, how the property is measured/reported (which decides binary vs. enumerated values and any thresholds), and alignment with existing ontologies (NCIt/MONDO). A quality bar rejects thin or unsourced entries.
34+
2. **Scaffold correctly.** It allocates the next identifier
35+
(`ECC-{MORPH|MOLEC}-NNNNNN`, six zero-padded digits) and a matching
36+
`NNNNNN-slug.yml` filename in the right folder, and writes a schema-valid entry
37+
honoring the `state` lifecycle (`draft``proposed``provisional`
38+
`adopted`) and `deny_unknown_fields`.
39+
3. **Validate.** It runs `cargo run -p ecc-cli -- check ecc` and fixes any
40+
failures before finishing.
41+
42+
### Usage
43+
44+
Start an agent in the repository root and describe the characteristic, e.g.:
45+
46+
> Use the create-ecc skill to add a molecular characteristic for MYCN
47+
> amplification.
48+
49+
See [`.claude/skills/create-ecc/SKILL.md`](.claude/skills/create-ecc/SKILL.md)
50+
for the full workflow and schema reference.
51+
52+
[claude-code]: https://www.anthropic.com/claude-code
53+
```
54+
2355
## 🚧️ Tests
2456
2557
Before submitting any pull requests, please make sure the code passes the

0 commit comments

Comments
 (0)