Contributing

Manual Curation Pipeline

The exact commands to take a skill from discovery to a closed intake. No AI required. Every phase with every command, typed by a human.

⚡ Quick path — 2 approvals, everything else automated
gaia curate https://github.com/owner/repo [--generic <id>] [--discover]
🛑 Gate 1 — Topology Confirm mapping + upstream URL. ~30 sec.
🛑 Gate 2 — Evidence + Stars Approve verified rows + auto-computed rating.
✅ Auto-merged CI green → merge → docs.

The reference below explains what runs inside each gate. Use it when you need full control or are debugging a step.

Pipeline overview

#PhaseWhat you produceGate
1gaia-curateA discovery-packet-v2 JSON in registry-for-review/discovery-packets/Human L4
2L4 ReviewYou append l4Resolution to the packetHard stop — must be you
3gaia push → PRIntake issue opened; draft PR on a review/meta branchCI green
4ev-pipelineVerified evidence lake ready for ingestHuman approves evidence
5gaia-ingestEvidence rows written, TM appraised, stars calibratedHuman approves calibration
6ClosePR merged, intake issue closed with findings commentDone
1

gaia-curate — Discover & package the skill

You have a real repo with a SKILL.md. Run prefill, apply the 6-rule mapping decision, write the packet, validate. Nothing touches the registry yet.

Step 1 — Preflight

bashclick to copy
# confirm gaia CLI is installed
gaia --version

# confirm gh CLI is authenticated
gh auth status

# confirm python3 available
python3 --version

Step 2 — Snapshot the generic list

Save this file. It's the trust anchor for packet validation. Don't overwrite it mid-run.

bashclick to copy
gaia dev list --generic --json > /tmp/generic-snapshot.json
wc -l /tmp/generic-snapshot.json

Step 3 — Run prefill against the SKILL.md URL

bashclick to copy
gaia dev prefill \
  --source "https://github.com/owner/repo/blob/main/SKILL.md" \
  --output /tmp/prefill-output.json

cat /tmp/prefill-output.json | python3 -m json.tool | head -80

Step 4 — Apply the 6-rule mapping decision

Rule (first match wins)DecisionWhen
1NOT_A_SKILLartifactGate != "valid-skill"
2DUPLICATEexactDedupe != null
3DEFERambiguity != null
4NEW_GENERICnTotal == 0
5MAPnStrong == 1 — use that genericId
6DEFERAll other cases (weak only, or nStrong ≥ 2)

Count nStrong = entries with matchTier == "strong" in mappingOptions[]. Count nTotal = total entries. Do not re-rank.

Step 5 — Write and validate the discovery-packet-v2

Create the packet at registry-for-review/discovery-packets/owner--skill-name.json. Key fields:

json — minimum required fieldsclick to copy
{
  "schemaVersion": "discovery-packet-v2",
  "source": { "url": "<blob-url>", "canonicalUrl": "<blob-url>", "lane": "github-skill-file" },
  "normalized": { "name": "verbatim from frontmatter", "description": "verbatim" },
  "contentSha256": "<sha256 of SKILL.md content>",
  "exactDedupe": null,
  "mappingOptions": [ /* copy from prefill-output.json */ ],
  "decision": "MAP",
  "reasonCode": "MAP_EXISTING_GENERIC",
  "selectedGenericId": "<id from strong option>",
  "genericSnapshot": { "command": "gaia dev list --generic --json", "contentSha256": "<hash>", "generics": [ /* snapshot contents */ ] },
  "lifecycle": "review-ready"
}
bash — validateclick to copy
python3 scripts/validate_discovery_packet.py \
  --generic-snapshot /tmp/generic-snapshot.json \
  registry-for-review/discovery-packets/owner--skill-name.json

# Must exit 0 with no MALFORMED_PACKET or MISSING_REQUIRED_FIELD errors
🛑
Stop — L4 Human Gate

Review the packet carefully before continuing. The next step writes it to the intake queue.

2

L4 Review — You ratify the topology

No one else does this step. Check the packet, append l4Resolution, re-validate.

What to check

  • Mapping decision is correct — does selectedGenericId match the skill's actual capability?
  • If NEW_GENERIC: is the proposed name and description vendor-neutral and falsifiable?
  • source.url is a real blob/ GitHub URL — not tree/ or a listing page.
  • normalized.description is verbatim from the SKILL.md frontmatter — not paraphrased.
  • Similarity score (mappingOptions[].similarity) and matchTier make sense.

Append l4Resolution

json — append to packetclick to copy
"l4Resolution": {
  "generic": { "id": "final-generic-id", "name": "Human Readable Name", "description": "Vendor-neutral, falsifiable.", "type": "basic", "prerequisites": [] },
  "named": { "contributor": "github-handle", "skillName": "kebab-case-name" },
  "upstreamSkillFileUrl": "https://github.com/owner/repo/blob/main/SKILL.md"
}
bash — re-validate after appendingclick to copy
python3 scripts/validate_discovery_packet.py \
  --generic-snapshot /tmp/generic-snapshot.json \
  registry-for-review/discovery-packets/owner--skill-name.json
3

gaia push → Draft PR — Open the intake issue

bashclick to copy
git checkout -b review/meta/github-handle--skill-name

# Dry run first
gaia push --from-file registry-for-review/discovery-packets/owner--skill-name.json --dry-run

# Real run — opens intake issue (auto-labels: intake + needs-triage)
gaia push --from-file registry-for-review/discovery-packets/owner--skill-name.json

git add registry-for-review/discovery-packets/owner--skill-name.json
git commit -m "feat(intake): curate contributor/skill-name [closes #ISSUE]"
git push -u origin review/meta/github-handle--skill-name
gh pr create --draft --title "feat(intake): ..." --body-file /tmp/pr-body.md

intake:* label lifecycle

These are machine gates — intake-approval.yml watches for them and fires automatically.

LabelWho appliesWhat it triggers
intakeAuto (gaia push)Routes into intake queue
needs-triageAuto (gaia push)Marks as awaiting review
intake:topology-approvedMaintainer onlyWorkflow fires: adds evidence-review, removes needs-triage
intake:evidence-reviewAuto (workflow)Signals agent to prepare Stage-1 seed
intake:evidence-readyAgent / youEvidence plan ready for human approval
intake:evidence-approvedMaintainer onlyOpens the single draft promotion PR
intake:rejectedMaintainer onlyCloses intake; no automation fires

intake:evidence-approved requires both intake:evidence-review and intake:evidence-ready to already be present. The workflow errors if either is missing.

bash — approve topology when ready (maintainer only)click to copy
gh issue edit <ISSUE_NUMBER> --add-label "intake:topology-approved"
# Fires intake-approval.yml — watch it:
gh run list --workflow=intake-approval.yml
4

ev-pipeline — Verify evidence before ingesting

Operates on evidence/by-type/ files only. Never touches registry/. Each phase produces review artifacts; you decide what to approve.

Phase 0 — ev-discovery (skippable)

The only phase that searches the web for new evidence. Skip for routine Stage-1 intakes. Run when you need benchmark-result, arxiv, peer-review, or richer social-signal rows.

Requires FIRECRAWL_API_KEY. Skip gracefully if absent.

bashclick to copy
gaia dev discover \
  --skill contributor/skill-id \
  --repo "https://github.com/owner/repo" \
  --types benchmark-result,arxiv,peer-review,social-signal \
  --output evidence/discovery/contributor--skill-id.md

Phase 1 — ev-collection

This runs on the entire registry — not just your new skill. generate_source_dump.py reads all named-skill evidence rows across every skill in registry/named/. Your new skill's rows appear alongside all others. That is expected.

bashclick to copy
python3 evidence/scripts/generate_source_dump.py \
  --output-dir evidence --by-type-dir evidence/by-type

python3 evidence/scripts/compile_data_lake.py \
  --sources evidence/by-type --lake evidence

Phase 2 — ev-star-verification

bashclick to copy
# Check auth first — zero stars from an unauth'd call is poison data
gh auth status
gh api repos/OWNER/REPO --jq '.stargazers_count'
# Flag rows where recorded stars differ from live count. Do NOT silently update.

Phase 3 — ev-adversarial-audit

bash — check for common issuesclick to copy
# Find github tree/ URLs that should be blob/
grep -rn "github.com/.*/tree/" evidence/by-type/

# Find subjective wording not backed by source
grep -rni "elite\|high-quality\|best-in-class\|leading" evidence/by-type/

Phase 4 — ev-link-validation

bashclick to copy
python3 evidence/scripts/validate_sources.py
# Or a 10-URL sample first:
python3 evidence/scripts/validate_sources.py 10
🛑
Human Evidence Gate

Review the source report. Approve rows to ingest. Remove dead-link, subjective, or type-mismatched rows. Only pass live, correctly scoped rows to Phase 5.

5

gaia-ingest — Write evidence to the named skill

First time mutating registry/. Every row uses --no-build. One build at the end. You approve calibration before it runs.

Ingest each approved evidence row

bash — repo-ownclick to copy
GAIA_OPERATOR_OVERRIDE=1 gaia dev evidence contributor/skill-id \
  "https://github.com/owner/repo" \
  --type repo-own --commits 847 --contributors 12 \
  --notes "Official upstream repo. Counts verified via GitHub API." \
  --source-started-at 2024-03-01 --no-build
bash — github-stars-ownclick to copy
GAIA_OPERATOR_OVERRIDE=1 gaia dev evidence contributor/skill-id \
  "https://github.com/owner/repo/blob/main/SKILL.md" \
  --type github-stars-own --stars 3421 --skill-count-in-repo 1 \
  --notes "Official SKILL.md. Star count verified live via gh api." \
  --source-started-at 2024-03-01 --no-build
bash — build + appraise + calibrateclick to copy
# Single build after all rows are written
GAIA_OPERATOR_OVERRIDE=1 gaia dev build

# Appraise Trust Magnitude
PYTHONPATH=src python3 scripts/trust_appraise.py --skill contributor/skill-id

# Only after you approve the proposed calibration:
GAIA_OPERATOR_OVERRIDE=1 gaia dev calibrate contributor/skill-id --stars 2
GAIA_OPERATOR_OVERRIDE=1 gaia dev validate

TM grade reference

Trust Magnitude is the sole promotion gate under Yggdrasil II. Thresholds sourced from src/gaia_cli/grading.py and META.md §1.1.

GradeTM floorStars it gatesNotes
ungraded< 201★–2★Stage-1 minimum (Awakened / Named baseline)
C≥ 20up to 3★Badge unlock floor at 2★ Named
B≥ 50up to 3★Solid adoption signals (Evolved)
A≥ 100gates 4★4★ Extra/Unique gate — Origin + TM ≥ 100
S≥ 250 + diversitygates 5★–6★Diversity gate: ≥3 evidence types + non-self-producible row. 5★ = TM ≥ 250. 6★ Apex adds 6-predicate gate.

The per-star Evidence Floor is retired. TM is the sole gate. But the Star Bar (installability, 3★+ requires a verified GitHub blob/ link) still applies.

6

Close — Merge PR & post intake comments

bashclick to copy
gh pr ready <PR_NUMBER>
gh pr checks <PR_NUMBER>

# When CI is green:
gh pr merge <PR_NUMBER> --subject "feat(registry): ingest contributor/skill-name [closes #ISSUE]"

# Post findings comment on PR (evidence table + TM + badge status)
gh pr comment <PR_NUMBER> --body-file /tmp/pr-close-comment.md

# Post closing comment on intake issue (path-to-promotion, @contributor tag)
gh issue comment <ISSUE_NUMBER> --body-file /tmp/issue-close-comment.md
gh issue close <ISSUE_NUMBER>

# Regenerate Class S site artifacts
GAIA_OPERATOR_OVERRIDE=1 gaia dev docs
git add docs/graph/ && git commit -m "chore: regenerate Class S artifacts" && git push

Common errors

UNTRUSTED_GENERIC_SNAPSHOT

The contentSha256 in the packet doesn't match the snapshot file passed to --generic-snapshot.

bash — recompute the hashclick to copy
python3 -c "import json,hashlib; d=json.load(open('/tmp/generic-snapshot.json')); print(hashlib.sha256(json.dumps(d,sort_keys=True,separators=(',',':')).encode()).hexdigest())"

INVALID_GENERIC_SELECTION — mapped ID not in snapshot

You used a genericId that wasn't in the snapshot you captured. Re-capture the snapshot after adding the new generic, or use an ID that's actually there.

gaia dev evidence fails — "unknown evidence type"

bashclick to copy
gaia dev evidence --help
# Lists all supported --type values and required flags

gaia dev validate fails after ingest

bashclick to copy
GAIA_OPERATOR_OVERRIDE=1 gaia dev validate --verbose
# Read the first error — usually a missing field or schema mismatch

Cheat sheet — every command in order

bash — full pipeline sequenceclick to copy
# ── Phase 1: Curate ──────────────────────────────────────────
gaia dev list --generic --json > /tmp/generic-snapshot.json
gaia dev prefill --source "<blob-url>" --output /tmp/prefill-output.json
# ... write packet JSON ...
python3 scripts/validate_discovery_packet.py --generic-snapshot /tmp/generic-snapshot.json <packet>.json

# ── Phase 2: L4 ──────────────────────────────────────────────
# Append l4Resolution to packet, re-validate

# ── Phase 3: Push + PR ───────────────────────────────────────
git checkout -b review/meta/handle--skill
gaia push --from-file <packet>.json --dry-run
gaia push --from-file <packet>.json           # auto-labels issue: intake + needs-triage
git add . && git commit -m "feat(intake): ..." && git push -u origin <branch>
gh pr create --draft --title "..." --body-file /tmp/pr-body.md
gh issue edit <ISSUE> --add-label "intake:topology-approved"  # maintainer only
gh issue edit <ISSUE> --add-label "intake:evidence-approved"   # maintainer only, after evidence-ready

# ── Phase 4: ev-pipeline ─────────────────────────────────────
# Phase 0 (skippable)
gaia dev discover --skill contributor/skill --repo "<url>" --types arxiv,peer-review,social-signal
# Phase 1 (whole-registry lake rebuild)
python3 evidence/scripts/generate_source_dump.py --output-dir evidence --by-type-dir evidence/by-type
python3 evidence/scripts/compile_data_lake.py --sources evidence/by-type --lake evidence
gh api repos/OWNER/REPO --jq '.stargazers_count'   # phase 2 star check
grep -rn "github.com/.*/tree/" evidence/by-type/      # phase 3 adversarial
python3 evidence/scripts/validate_sources.py          # phase 4 link health

# ── Phase 5: gaia-ingest ─────────────────────────────────────
GAIA_OPERATOR_OVERRIDE=1 gaia dev evidence contributor/skill "<url>" \
  --type repo-own --commits N --contributors N --notes "..." --source-started-at YYYY-MM-DD --no-build
# ... repeat for each evidence type ...
GAIA_OPERATOR_OVERRIDE=1 gaia dev build
PYTHONPATH=src python3 scripts/trust_appraise.py --skill contributor/skill
GAIA_OPERATOR_OVERRIDE=1 gaia dev calibrate contributor/skill --stars N  # after your approval
GAIA_OPERATOR_OVERRIDE=1 gaia dev validate

# ── Phase 6: Close ───────────────────────────────────────────
gh pr ready <PR> && gh pr checks <PR>
gh pr merge <PR> --subject "feat(registry): ... [closes #ISSUE]"
gh pr comment <PR> --body-file /tmp/pr-close-comment.md
gh issue comment <ISSUE> --body-file /tmp/issue-close-comment.md
gh issue close <ISSUE>
GAIA_OPERATOR_OVERRIDE=1 gaia dev docs

Want to automate this? Become a contributor.

Once you've curated a skill manually, you can contribute back to the registry directly using gaia dev commands — the same CLI the pipeline runs under the hood. No intake queue. Direct mutations with your approval.

What you want to doCommand
Add a generic skill nodegaia dev add "Name" --id kebab-id --type basic --description "..."
Add a named implementationgaia dev named --contributor handle --skill slug --generic id --upstream <blob-url>
Add an evidence rowgaia dev evidence contributor/skill "<url>" --type repo-own --commits N ...
Appraise Trust MagnitudePYTHONPATH=src python3 scripts/trust_appraise.py --skill contributor/skill
Calibrate star levelgaia dev calibrate contributor/skill --stars N
Fuse a suite capstonegaia dev fuse <id> --name "..." --prereqs id1,id2 --named-capstone contributor/slug
Validate registryGAIA_OPERATOR_OVERRIDE=1 gaia dev validate
Regenerate site artifactsGAIA_OPERATOR_OVERRIDE=1 gaia dev docs

All gaia dev mutations require GAIA_OPERATOR_OVERRIDE=1 or maintainer permissions. Read Contributing §1C before making direct registry changes. Or run gaia curate <url> to automate the full pipeline with 2 human gates.