agentsclimarketplace

Kaggle

Skill Borda/AI-Rig/plugins/cc_research/skills/kaggle

A collection of personal AI coding assistant configurations, specialist agents, and automated workflows optimized for Python and ML open-source development.

Install
npx -y skills add Borda/AI-Rig --skill kaggle

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 23 stars23 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Generate a Kaggle competition notebook as a Jupytext `# %%` Python script following the user's established ML research style: PTL for DNN training, best-fit tool selection, EDA→Baseline→Train→Inference pipeline with per-stage lens cells, small single-purpose cells each carrying a why. Tuned to win (leakage-safe CV, metric-aligned modeling) as much as to teach. Writes output to .experiments/kaggle/<name>.py.

SKILL.md

19.2 KB, as published. Nobody here has run it

<objective>

Generate Kaggle competition notebook script, Jupytext # %% format.

Two goals, equal weight — neither traded for other:

  • Win — leaderboard-competitive: leakage-safe CV, metric-aligned loss/model choice, tuning/ensembling when it moves the score, not style theater
  • Teach — read top to bottom like a university/seminar lecture on solving this competition: reader new to it follows the full reasoning chain, every decision motivated, nothing left as unexplained code

Follows user's ML research style distilled from past notebooks:

  • PTL always for DNN training (PyTorch Lightning + torchmetrics) — even simple baselines
  • Tool agnostic — best-fit library for problem; PTL when training loop needed
  • Stages with lenses — each major stage: quick sanity check cell (show one batch, print shapes, verify submission format)
  • Small, single-purpose cells — one action per cell (load, one transform, one plot, one check); never bundle setup + run + verify to save cell count
  • Every cell earns its place — one-line why (comment or markdown sentence) before/in each cell: the specific reason this step happens now — never a restatement of what the code does
  • Section markdown is extensive and structured — full explanation of what/why/how-it-advances-the-goal per section, formatted as tables/lists/blockquotes over dense prose paragraphs; markdown before a plot sets up the question, markdown after states the finding and its implication — plot and prose flow as one beat, never an orphaned chart
  • # ! bash over subprocess — package installs, nvidia-smi, ls -lh, # ! head submission.csv
  • EDA is visual — distribution plots, sample grids, dimension scatters before any model
  • Inference included — model save pattern + separate load-and-infer cells
  • CSVLogger + seaborn — metrics plotted from metrics.csv after every training run

NOT for writing Python packages, modules, production code — notebook scripts only. NOT research literature survey — use /research:topic for SOTA literature search.

</objective> <inputs>
  • $ARGUMENTS: one of:
    • <competition-name> — short slug for output filename; generates blank template
    • <competition-name> <url> — fetches competition overview from URL before generating
    • <competition-name> "<description>" — inline description of problem and data
    • --type <type> — hint: classification, regression, segmentation, detection, tabular (auto-detected when omitted)
    • --eda-only — generate only EDA sections (no model/training/submission); always online (no offline setup)
    • --inference-only — generate inference notebook from checkpoint (no EDA, no training); always offline (frozen packages pattern); loads checkpoint from PATH_CHECKPOINT constant; output suffix -inference.py
    • --offline-setup — include offline package setup (frozen_packages pattern) in setup cell; auto-applied when --inference-only; ignored when --eda-only (EDA always online)
    • --resume <path> — read existing .py script, extend/improve it

Output: .experiments/kaggle/<competition-name>.py

</inputs> <constants>
OUTPUT_DIR:    .experiments/kaggle/
CELL_MARK:     "# %%"
MD_CELL_MARK:  "# %% [markdown]"
# NOTE: documentation-only — not referenced as shell vars across separate Bash() calls (state doesn't persist); keep values in sync with literal use sites (Steps 1, 3, 4).
</constants> <compaction>

Key boundary: end of Step 3 — notebook script generated by foundry:sw-engineer, written to OUTFILE. Preserve: OUTFILE path (derived from TMPDIR keys), COMPETITION_NAME (TMPDIR key), mode flags (EDA_ONLY, INFERENCE_ONLY, OFFLINE_SETUP). Clear at Step 1 start (stale prior run) and after Step 4 package-distillation gate resolves.

</compaction> <workflow>

Task hygiene: call TaskList first; close orphaned tasks. Create tasks per phase.

Step 1: Parse arguments and gather context

# loads: compaction-contract.md
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
ARGS="$ARGUMENTS"
COMPETITION_NAME=$(echo "$ARGS" | awk '{print $1}')
RESUME_FLAG=""
EDA_ONLY=false
INFERENCE_ONLY=false
OFFLINE_SETUP=false
PROBLEM_TYPE=""

[[ "$ARGS" == *"--eda-only"* ]]      && EDA_ONLY=true
[[ "$ARGS" == *"--inference-only"* ]] && INFERENCE_ONLY=true
[[ "$ARGS" == *"--offline-setup"* ]]  && OFFLINE_SETUP=true
[[ "$ARGS" =~ --type[[:space:]]([a-z]+) ]] && PROBLEM_TYPE="${BASH_REMATCH[1]}"
[[ "$ARGS" =~ --resume[[:space:]]([^[:space:]]+) ]] && RESUME_FLAG="${BASH_REMATCH[1]}"

# inference always offline; EDA always online (overrides --offline-setup)
[ "$INFERENCE_ONLY" = "true" ] && OFFLINE_SETUP=true
[ "$EDA_ONLY" = "true" ]       && OFFLINE_SETUP=false

echo "Competition: $COMPETITION_NAME"
echo "Type: ${PROBLEM_TYPE:-auto-detect}"
echo "EDA only: $EDA_ONLY | Inference only: $INFERENCE_ONLY | Offline setup: $OFFLINE_SETUP"

# Persist for Steps 3+4 (bash state lost across Bash() calls)
echo "$COMPETITION_NAME" > "${TMPDIR:-/tmp}/kaggle-competition-name-${CSID}"
echo "$EDA_ONLY"         > "${TMPDIR:-/tmp}/kaggle-eda-only-${CSID}"
echo "$INFERENCE_ONLY"   > "${TMPDIR:-/tmp}/kaggle-inference-only-${CSID}"
echo "$OFFLINE_SETUP"    > "${TMPDIR:-/tmp}/kaggle-offline-setup-${CSID}"

mkdir -p .experiments/kaggle/  # timeout: 3000
KEEP_ITEMS=""
if [[ "$ARGS" =~ --keep[[:space:]]\"([^\"]+)\" ]]; then
    KEEP_ITEMS="${BASH_REMATCH[1]}"
fi
# Clear stale contract from any prior incomplete run (compaction-contract.md §Lifecycle)
rm -f .temp/state/skill-contract.md  # timeout: 5000
echo "${KEEP_ITEMS:-}" > "${TMPDIR:-/tmp}/kaggle-keep-items-${CSID}"  # persist for Step 3 contract write

Flag mutual-exclusion check — if EDA_ONLY and INFERENCE_ONLY are both true (both --eda-only and --inference-only passed): print ! Conflicting flags: `--eda-only` and `--inference-only` are mutually exclusive (`--eda-only` is always-online with no training; `--inference-only` is always-offline/frozen-package with no EDA — see `foundation.md`). Pick one. then invoke AskUserQuestion — (a) Abort · (b) Continue ignoring both (falls back to full mode: neither eda-only nor inference-only applied). On Abort: stop.

Unsupported flag check — scan $ARGUMENTS for remaining --<token> tokens after supported flags extracted (--eda-only, --inference-only, --offline-setup, --type, --resume, --keep). Found: print ! Unknown flag(s): `--<token>`. Supported: `--eda-only`, `--inference-only`, `--offline-setup`, `--type <type>`, `--resume <path>`, `--keep "<items>"`. then invoke AskUserQuestion — (a) Abort · (b) Continue ignoring. On Abort: stop.

Context collection — run in parallel:

  1. URL provided in args: WebFetch competition page; extract problem description, target metric, data format, evaluation — read and quote actual text, never paraphrase from training knowledge
  2. --resume: read existing script (Read tool)
  3. Scan .experiments/kaggle/ (Glob pattern *.py) for prior scripts; read first 30 lines of each — find similar past competitions, use as structural reference
  4. Check resources/competitors/ for .ipynb/.py files — found: read each, summarise approach (model choice, preprocessing, feature engineering, augmentation). Use findings to inform detection method and domain-specific preprocessing decisions in Step 2.

Grounding protocol — mandatory before Step 2:

Build fact table. Each fact needs source: [fetched], [user], [past-notebook:<file>], or [inferred-from:<fact>]. Never mark fact [inferred] without citing prior fact it derives from.

FactValueSource
problem_type??
input_modality??
output_format??
eval_metric??
data schema (CSV columns / image format)??
submission format??

Gaps — ask before generating:

After building fact table, count facts still marked ? or [inferred] without prior grounded fact. Any of these unknown:

  • input_modality — cannot generate Dataset class
  • eval_metric — cannot choose torchmetric
  • submission format — cannot generate Submission section

Invoke AskUserQuestion with up to 4 questions covering all unknown required facts. Never guess or hallucinate competition-specific details (column names, file paths, data schema). State "unknown — will use placeholder" if user skips.

Acknowledge past-notebook similarity explicitly: "Found similar past notebook: <file> — reusing <pattern> from it."

Step 2: Determine problem profile

From gathered context, determine:

PropertyValue
problem_typeclassification / regression / segmentation / detection / tabular
input_modalityimage-2d / image-3d / tabular / time-series / point-cloud / mixed
output_formatlabel / scalar / mask / bboxes / rle
eval_metricAUC / F1 / RMSE / Dice / IoU / mAP / ...
recommended_modelsee §Model selection below
use_ptltrue if DNN training; false for pure XGBoost/sklearn pipelines

Model selection rules (best-fit, not default):

  • Image classification → timm.create_model (EfficientNetV2, ConvNeXt, ViT-B) + PTL
  • Image regression → timm.create_model backbone (num_classes=0) + PTL regression head
  • Image segmentation → segmentation_models_pytorch (UNet/UNet++) + PTL; MONAI for 3D
  • Object detection → torchvision.models.detection or ultralytics YOLO + PTL wrapper if needed
  • Tabular → xgboost.XGBClassifier/Regressor with sklearn Pipeline; PTL only if DNN features needed
  • Point cloud → MONAI or pytorch3d; PTL always
  • Time series → torch.nn.LSTM or tsfresh features + XGBoost; PTL when DNN

PTL rule: use PTL whenever training loop needed — even simple single-layer models. Exception: pure sklearn/XGBoost pipelines, no neural network component.

Step 3: Generate notebook script

Foundry availability check — verify before spawning:

FOUNDRY_AVAILABLE=$(ls -td ~/.claude/plugins/cache/borda-ai-rig/foundry/*/agents/sw-engineer.md 2>/dev/null | head -1)  # timeout: 5000
[ -z "$FOUNDRY_AVAILABLE" ] && { printf "⚠ foundry plugin not available — kaggle notebook generation requires foundry:sw-engineer\nInstall: claude plugin install foundry@borda-ai-rig\n"; exit 1; }

Spawn prompt assembled from the inline problem profile below plus exactly one resolved composition row:

# Re-hydrate flags persisted in Step 1 (bash state lost between Bash calls)
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r COMPETITION_NAME < "${TMPDIR:-/tmp}/kaggle-competition-name-${CSID}" 2>/dev/null || COMPETITION_NAME="$COMPETITION_NAME"
IFS= read -r EDA_ONLY < "${TMPDIR:-/tmp}/kaggle-eda-only-${CSID}" 2>/dev/null || EDA_ONLY="false"
IFS= read -r INFERENCE_ONLY < "${TMPDIR:-/tmp}/kaggle-inference-only-${CSID}" 2>/dev/null || INFERENCE_ONLY="false"
_KAGGLE_MODES="${CLAUDE_PLUGIN_ROOT:-plugins/cc_research}/skills/kaggle/modes"
COMPOSITION_FILE="$_KAGGLE_MODES/composition.md"
MODE="full"
[ "$EDA_ONLY" = "true" ] && MODE="eda-only"
[ "$INFERENCE_ONLY" = "true" ] && MODE="inference-only"

# Derive output filename from mode — must match the composition contract before spawning
OUTPUT_SUFFIX=""
[ "$INFERENCE_ONLY" = "true" ] && OUTPUT_SUFFIX="-inference"
OUTFILE=".experiments/kaggle/${COMPETITION_NAME}${OUTPUT_SUFFIX}.py"
echo "$MODE" > "${TMPDIR:-/tmp}/kaggle-mode-${CSID}"
echo "Mode: $MODE · Output: $OUTFILE"
cat "$COMPOSITION_FILE"  # timeout: 5000

Select the exact $MODE row from composition.md (loaded above) and cat each named contract once, from left to right, plus style-rules.md once:

_KAGGLE_MODES="${CLAUDE_PLUGIN_ROOT:-plugins/cc_research}/skills/kaggle/modes"
case "$MODE" in
  full) _CONTRACTS="foundation.md eda.md training.md inference.md submission.md" ;;
  eda-only) _CONTRACTS="foundation.md eda.md" ;;
  inference-only) _CONTRACTS="foundation.md inference.md submission.md" ;;
esac
for _c in $_CONTRACTS style-rules.md; do
    echo "=== $_c ==="
    cat "$_KAGGLE_MODES/$_c"
done

Load modality-dispatch.md only when a selected section requests a modality branch:

_KAGGLE_MODES="${CLAUDE_PLUGIN_ROOT:-plugins/cc_research}/skills/kaggle/modes"
cat "$_KAGGLE_MODES/modality-dispatch.md"  # timeout: 5000

Do not load unselected section contracts. Pass the selected row and resolved contract contents to foundry:sw-engineer after the problem profile block below.

Spawn foundry:sw-engineer with this prompt preamble (inline, then continue with the resolved composition contracts):

Write a complete Kaggle competition notebook script to `<OUTFILE>` (substitute expanded path from bash block above).

Format: Jupytext `# %%` Python script — every cell separated by `# %%` (code) or `# %% [markdown]` (markdown).

## Problem profile
- Competition: <competition-name>
- Problem type: <problem_type>
- Input: <input_modality>
- Output: <output_format>
- Metric: <eval_metric>
- Model: <recommended_model>
- Use PTL: <use_ptl>
- Description: <competition description if available>

[Continue with the selected row from composition.md, followed by the resolved section contracts in order, style-rules.md, and the selected modality branch when applicable.]

## Completion

Write `<OUTFILE>`. Return only:

{"status":"done","file":"<OUTFILE>","lines":N,"sections":N,"problem_type":"<type>","mode":"<MODE>","confidence":0.N}

Synchronous spawn note: foundry:sw-engineer spawned synchronously (not run_in_background=true), so CLAUDE.md §6 poll-based monitoring unreachable mid-call. After Agent() returns, check agent's output under .experiments/kaggle/; missing or empty → treat as timed out, surface with ⏱ marker — never silently omit.

# Compaction contract — boundary: after Step 3 notebook generated (compaction-contract.md §Lifecycle)
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r _COMPETITION < "${TMPDIR:-/tmp}/kaggle-competition-name-${CSID}" 2>/dev/null || _COMPETITION=""
IFS= read -r _INF < "${TMPDIR:-/tmp}/kaggle-inference-only-${CSID}" 2>/dev/null || _INF="false"
IFS= read -r _KEEP < "${TMPDIR:-/tmp}/kaggle-keep-items-${CSID}" 2>/dev/null || _KEEP=""
_SUFFIX=""; [ "$_INF" = "true" ] && _SUFFIX="-inference"
_OUTFILE=".experiments/kaggle/${_COMPETITION}${_SUFFIX}.py"
_KEEP_APPEND=""; [ -n "$_KEEP" ] && _KEEP_APPEND="; user-keep: $_KEEP"
mkdir -p .temp/state  # timeout: 5000
{
    echo "## Active Skill Contract"
    echo "- skill: research:kaggle · phase: verify (after Step 3 notebook generated)"
    echo "- run-dir: .experiments/kaggle"
    echo "- preserve: outfile=${_OUTFILE}, competition=${_COMPETITION}${_KEEP_APPEND}"
    echo "- next: Step 4 verify structure, follow-up gate, package distillation"
} > .temp/state/skill-contract.md  # timeout: 5000

Step 4: Verify and report

After agent completes:

  1. Read first 30 lines of generated file to verify # %% structure
  2. Count cell markers: grep -c "^# %%" .experiments/kaggle/<name>.py
  3. Resolve the current row from composition.md; verify every listed section is present and no unlisted section was generated
  4. Mechanically check for bare # heading-spacer lines (style-rules.md rule 13) — prose compliance alone proved insufficient in practice; auto-fix rather than trust the generating pass
# Re-derive OUTFILE from flags persisted in Step 1 (bash state lost between steps)
export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}"
IFS= read -r COMPETITION_NAME < "${TMPDIR:-/tmp}/kaggle-competition-name-${CSID}" 2>/dev/null || COMPETITION_NAME="$COMPETITION_NAME"
IFS= read -r INFERENCE_ONLY < "${TMPDIR:-/tmp}/kaggle-inference-only-${CSID}" 2>/dev/null || INFERENCE_ONLY="false"
IFS= read -r MODE < "${TMPDIR:-/tmp}/kaggle-mode-${CSID}" 2>/dev/null || MODE="full"
OUTPUT_SUFFIX=""; [ "$INFERENCE_ONLY" = "true" ] && OUTPUT_SUFFIX="-inference"
OUTFILE=".experiments/kaggle/${COMPETITION_NAME}${OUTPUT_SUFFIX}.py"
echo "=== Composition ==="; echo "$MODE"
echo "=== Cell count ==="; grep -c "^# %%" "$OUTFILE"  # timeout: 5000
echo "=== Sections ===";   grep "^# %% \[markdown\]" "$OUTFILE"  # timeout: 5000
echo "=== File size ===";  wc -l "$OUTFILE"  # timeout: 5000

echo "=== Bare '#' heading-spacer check (rule 13) ==="
BARE_HASH_COUNT=$(grep -cE '^#+[[:space:]]*$' "$OUTFILE" 2>/dev/null || echo 0)
echo "Found: $BARE_HASH_COUNT"
if [ "$BARE_HASH_COUNT" -gt 0 ]; then
    grep -nE '^#+[[:space:]]*$' "$OUTFILE"  # timeout: 5000
    python3 -c "
import re
path = '$OUTFILE'
with open(path) as f:
    text = f.read()
fixed = re.sub(r'(?m)^#+[ \t]*$', '', text)
with open(path, 'w') as f:
    f.write(fixed)
"  # timeout: 5000
    echo "Auto-fixed: $BARE_HASH_COUNT bare '#' spacer line(s) converted to true blank lines"
fi

Print to terminal:

  • Output path ($OUTFILE)
  • Mode + resolved composition contracts
  • Problem type + recommended model
  • Cell count and section list
  • Missing required sections flagged with
  • Bare # heading-spacer count found/auto-fixed (0 when clean)

Invoke AskUserQuestion as follow-up gate:

  • (a) Open in editor — ! code $OUTFILE
  • (b) Extend with additional sections
  • (c) Regenerate with different model/approach
  • (d) Done

On (a): run ! code "$OUTFILE" via Bash. On (b): re-enter Step 3 with extension directive. On (c): re-enter Step 2 with user-specified changes.

Package distillation gate — invoke after follow-up gate resolves to Done:

Benefits to state before asking: shared helpers tested once, used everywhere; wheel attachment on Kaggle faster than re-inlining; subsequent notebooks shorter; package tests catch regressions before submission.

Invoke AskUserQuestion:

  • (a) Yes — scaffold src/<package>/ with extracted helpers + tests
  • (b) Skip — keep everything inlined for now

If (a):

  1. Identify every function in notebook with no hardcoded paths, no plt.show(), no tqdm calls
  2. Write each to src/<package>/<module>.py with full Google-style docstring + Example: block — all standard coding patterns apply (doctests for pure functions, Args:/Returns: sections, full if __name__ == "__main__": guards where appropriate); these are package modules, not notebook cells
  3. Create tests/test_<module>.py covering each function
  4. Create notebooks/01_<competition-name>_pkg.py — inline definitions replaced by package imports; never modify validated baseline $OUTFILE

If (b): skip; repeat this gate offer after next notebook written.

rm -f .temp/state/skill-contract.md  # clear contract — kaggle notebook complete (compaction-contract.md §Lifecycle)  # timeout: 5000
</workflow>

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.