Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions .claude/skills/create-ecc/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
name: create-ecc
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`.
---

# Create an ECC (composable characteristic)

Scaffold a new composable characteristic as a YAML file that deserializes cleanly
into the `ecc::Characteristic` model. The authoritative schema lives in
`crates/ecc/src/` — this skill mirrors it. If in doubt, read `crates/ecc/src/lib.rs`,
`crates/ecc/src/common.rs`, `crates/ecc/src/common/value/kind.rs`, and
`crates/ecc/src/identifier.rs` before writing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would extrapolate this out a bit more for the prior research you want the agent to do. So it should search available publications and present back to you a particular shape the characteristic might take. It should not fabricate anything and should disagree with you when it thinks you've stated something incorrectly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@claymcleod updated the PR, edited the PR description, and also added an issue #16 .

## 1. Pick the type, number, and identifier

Each ECC lives in one of two folders, and its identifier type must match:

| Type | Folder | Identifier prefix | Rust variant |
| ------------- | ------------ | ----------------- | ------------------------ |
| Morphological | `ecc/morph/` | `ECC-MORPH-` | `Identifier::Morphological` |
| Molecular | `ecc/molec/` | `ECC-MOLEC-` | `Identifier::Molecular` |

- **Identifier format**: `ECC-{MORPH|MOLEC}-NNNNNN` — prefix and type are
UPPERCASE, and the number is exactly **6 zero-padded digits**, starting at
`000001` (zero is invalid). Example: `ECC-MOLEC-000002`.
- **Filename**: `NNNNNN-kebab-case-name.yml` in the matching folder, using the
**same 6-digit number** as the identifier. Keep the filename number and the
identifier number in sync. Example: `ecc/molec/000002-mycn-amplification.yml`.
- Choose the next unused number by listing the target folder (e.g. `ls ecc/molec`).

## 2. Choose the `state` and its required fields

`state` is the enum tag (`crates/ecc/src/lib.rs`, `#[serde(tag = "state")]`,
`deny_unknown_fields` — so **no extra/unknown keys** are allowed). The state
determines which fields are required:

| `state` | Required fields |
| ------------- | --------------------------------------------------------------------- |
| `draft` | none — every common field is optional (use while still filling it in) |
| `proposed` | all common fields |
| `provisional` | all common fields |
| `adopted` | all common fields **plus** `adoption_date` (RFC 3339 timestamp) |

**Common fields** (from `crates/ecc/src/common.rs`), required for
proposed/provisional/adopted:

- `name` — string, human-readable title.
- `identifier` — the `ECC-…` identifier string (see step 1).
- `rfc` — a GitHub issue URL that MUST match
`https://github.com/stjudecloud/ecc/issues/<number>` (enforced by regex in
`crates/ecc/src/rfc.rs`).
- `description` — string; may be Markdown (block scalar `|` recommended).
- `values` — the value kind (see step 3).
- `references` — optional list; if present it must be **non-empty** (see step 4).

## 3. Define `values` (the value kind)

`values.kind` is the enum tag (`crates/ecc/src/common/value/kind.rs`,
`#[serde(tag = "kind")]`). One of:

- **`binary`** — a true/false determination (e.g. present/absent,
amplified/not amplified). Requires a `description` with a `"true"` and a
`"false"` entry, each an object with `summary` and `details`. **Quote the
`"true"`/`"false"` keys** so YAML does not parse them as booleans. `summary`
and `details` are sentences and must be non-empty.

```yaml
values:
kind: binary
description:
"true":
summary: A one-line summary of the true case.
details: |
A longer explanation of what "true" means for this characteristic.
"false":
summary: A one-line summary of the false case.
details: |
A longer explanation of what "false" means for this characteristic.
```

- **`categorical`** — a fixed set of string options:

```yaml
values:
kind: categorical
options:
- Option A
- Option B
```

- **`numerical`** — a measured number with a type and units. `type` is one of
`signed`, `unsigned`, or `float`:

```yaml
values:
kind: numerical
type: float
units: percent
```

## 4. Optional `references`

If included, `references` is a non-empty list. Each entry has a `kind` of
`manuscript` or `preprint` (`crates/ecc/src/common/reference.rs`) with:
`title` (string), `authors` (string), `context` (a non-empty sentence),
`url` (any valid URL), and `highlighted` (bool). Omit the whole `references`
key if you have none — do not write an empty list.

```yaml
references:
- kind: manuscript
title: The title of the paper.
authors: A. Author, B. Author
context: One sentence on why this paper is relevant to this ECC.
url: https://pubmed.ncbi.nlm.nih.gov/123456
highlighted: true
```

## 5. Full template (proposed, binary)

```yaml
state: proposed
name: <Human Readable Name>
identifier: ECC-MOLEC-NNNNNN
rfc: https://github.com/stjudecloud/ecc/issues/<n>
description: |
# Overview

A Markdown description of the characteristic.
values:
kind: binary
description:
"true":
summary: <summary of the true case>.
details: |
<details of the true case>
"false":
summary: <summary of the false case>.
details: |
<details of the false case>
```

`ecc/000000-example.yml` is a complete, valid reference example.

## 6. Validate

Always validate after writing the file. The checker globs `ecc/**/*.yml` and
deserializes each into `Characteristic`, printing `OK` or `FAIL`. The Cargo
workspace lives in `crates/`, so run it from the repo root with an explicit
manifest path (this matches CI's `ecc-cli check ecc`, which installs the binary
first and runs from the root):

```bash
cargo run --manifest-path crates/Cargo.toml -p ecc-cli -- check ecc
```

If a file `FAIL`s, read the diagnostic (it points at the offending location),
compare against the schema above, and fix — common causes: unquoted
`true`/`false` keys, wrong identifier padding or type, an `rfc` URL that is not a
`stjudecloud/ecc` issue, unknown/extra keys (`deny_unknown_fields`), or an empty
`references` list.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,38 @@ cargo build --release
cargo run --release --example
```

## 🤖 Authoring characteristics with Claude

This repository ships a [Claude Code][claude-code] skill, `create-ecc`, that
guides an agent through **researching and authoring** a new composable
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.

### What it does

1. **Research first.** Before writing anything, the agent builds an evidence
brief: a precise definition and scope, the correct category (`morph` vs
`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.
2. **Scaffold correctly.** It allocates the next identifier
(`ECC-{MORPH|MOLEC}-NNNNNN`, six zero-padded digits) and a matching
`NNNNNN-slug.yml` filename in the right folder, and writes a schema-valid entry
honoring the `state` lifecycle (`draft` → `proposed` → `provisional` →
`adopted`) and `deny_unknown_fields`.
3. **Validate.** It runs `cargo run -p ecc-cli -- check ecc` and fixes any
failures before finishing.

### Usage

Start an agent in the repository root and describe the characteristic, e.g.:

> Use the create-ecc skill to add a molecular characteristic for MYCN
> amplification.

See [`.claude/skills/create-ecc/SKILL.md`](.claude/skills/create-ecc/SKILL.md)
for the full workflow and schema reference.

[claude-code]: https://www.anthropic.com/claude-code
```

## 🚧️ Tests

Before submitting any pull requests, please make sure the code passes the
Expand Down
Loading