[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MYQTD4M2GMSJ1NTPS06Q7":3,"skill-same:01M71MYQTD4M2GMSJ1NTPS06Q7":147},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":14,"repositoryHtmlUrl":55,"repositoryHomepageUrl":56,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M71MYQTD4M2GMSJ1NTPS06Q7","earth2studio-create-prognostic",null,"Create Earth2Studio prognostic (time-stepping forecast) model wrappers. Do NOT use for diagnostic models, data sources, or installation.","pattanation\u002FNorvik","pattanation","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235419268?v=4","01M71M5THHYYB15ME8R2E4FCZG","Patta","01M71M5TJM1NDM992M8PDKYR2K",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"earth2studio create prognostic","create","installation","models","use","agent-skills","python","for","forecast","NVIDIA","do","path","data","data sources","team","URL","local","time","model","sources","2026-11-10 10:56:23",false,"---\nname: earth2studio-create-prognostic\nversion: 0.16.0\nlicense: Apache-2.0\nmetadata:\n  author: NVIDIA Earth-2 Team \u003Cagent-skills@nvidia.com>\n  tags: [earth2studio, prognostic-model, python]\ndescription: >\n  Create Earth2Studio prognostic (time-stepping forecast) model wrappers.\n  Do NOT use for diagnostic models, data sources, or installation.\nargument-hint: URL or local path to reference inference script (optional)\n---\n\n## Quick Start Checklist\n\n**Do these steps IN ORDER. Do not skip any step.**\n\n- [ ] Read this SKILL.md completely first\n- [ ] Get reference script (Step 0)\n- [ ] Create `earth2studio\u002Fmodels\u002Fpx\u002F\u003Cname>.py` with triple inheritance\n- [ ] Create `test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py` with mock tests\n- [ ] Run: `uv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py -v`\n- [ ] Add\u002Fupdate model extra, install docs, API docs, and changelog (Steps 1-2, 9)\n- [ ] Run: `make format && make lint`\n\n> **⚠️ CRITICAL:** Always use `uv run` for Python commands:\n> - ✅ `uv run pytest ...` \u002F `uv run python ...`\n> - ❌ `pytest ...` \u002F `python ...` (missing dependencies)\n>\n> **Stuck or wrong output:** Do not keep retrying the same fix. Follow\n> [Self-Improvement](#self-improvement) to patch this skill before continuing.\n\n## Purpose\n\nImplement a prognostic model wrapper connecting third-party ML weather models\nto Earth2Studio. Prognostic models time-integrate forward—given initial state,\nthey predict future states by stepping through time (e.g., 6-hour increments).\n\n## Workspace\n\n| Context | Location |\n|---------|----------|\n| Harbor eval | Write to `\u002Fworkspace\u002Foutput\u002Fearth2studio\u002Fmodels\u002Fpx\u002F...` |\n| Harbor + `--copy-repo` | Full checkout at `\u002Fworkspace\u002Frepo` |\n| Local clone | Directory with `pyproject.toml` |\n\n**Never read `evals\u002Ftargets\u002F`** — grader references only.\n\n### Reference Files\n\nLoad on demand during the matching step:\n\n| File | Content | Load at |\n|------|---------|---------|\n| `references\u002Fskeleton-template.py` | Full model skeleton with FILL comments | Steps 3–6 |\n| `references\u002Fmethod-templates.py` | Canonical method implementations | Steps 4–6 |\n| `references\u002Ftesting-guide.py` | Test skeleton and mock patterns | Step 7 |\n| `references\u002Fvalidation-guide.md` | Comparison scripts, PR, code review | Steps 10–11 |\n\n---\n\n## Workflow Steps\n\n### Step 0 — Get Reference Script\n\nIf `$ARGUMENTS` provided, use it. Otherwise ask:\n> Please provide a reference inference script URL\u002Fpath.\n\n### Step 1 — Analyze & Propose Dependencies\n\nAnalyze: packages, architecture, I\u002FO shapes, time step, resolution, checkpoint.\n\nPropose `pyproject.toml` group (alphabetical, add to `all`). Every\nprognostic model must have an optional dependency extra, even when no packages\nare required:\n```toml\nmodel-name = [\"package1>=version\", \"package2\"]\n# or, when no additional packages are required:\nmodel-name = []\n```\n\n**[CONFIRM]** Present dependencies and ask user to approve.\n\n### Step 2 — Add Dependencies\n\nEdit `pyproject.toml`: add the model extra alphabetically, even if it is\nempty, and update the `all` aggregate.\n\n### Step 3 — Create Model File\n\n**File:** `earth2studio\u002Fmodels\u002Fpx\u002F\u003Clowercase>.py`\n\n**Required inheritance (all three):**\n```python\nclass ModelName(torch.nn.Module, AutoModelMixin, PrognosticMixin):\n```\n\n**Required imports:**\n```python\nimport numpy as np\nimport torch\nfrom earth2studio.models.auto import AutoModelMixin, Package\nfrom earth2studio.models.batch import batch_coords, batch_func\nfrom earth2studio.models.px.base import PrognosticMixin\nfrom earth2studio.models.utils import create_coords_from_lat_lon, handshake_dim\nfrom earth2studio.lexicon import E2STUDIO_VOCAB\nfrom earth2studio.utils import check_optional_dependencies\nfrom loguru import logger\n```\n\n**SPDX header (required at top of every .py file):**\n```python\n# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES.\n# SPDX-License-Identifier: Apache-2.0\n```\n\n**Canonical method order:**\n1. `__init__` 2. `input_coords` 3. `output_coords` (@batch_coords)\n4. `load_default_package` 5. `load_model` 6. `to` (optional)\n7. Private methods 8. `__call__` (@batch_func) 9. `_default_generator`\n10. `create_iterator`\n\n### Step 4 — Implement Coordinates\n\n**input_coords rules:**\n- `batch`: `np.empty(0)`\n- `time`: `np.empty(0)` (dynamic)\n- `lead_time`: starts at `np.timedelta64(0, \"h\")`\n- `lat`: 90 to -90 (north to south); this is the public Earth2Studio convention even if the source model uses the opposite order\n- `lon`: 0 to 360\n- If a checkpoint\u002Fmodel core expects south-to-north latitude, flip tensors internally before\u002Fafter the core model; do not expose flipped latitude in `input_coords` or `output_coords`\n- Map variables to `E2STUDIO_VOCAB` (282 entries in `earth2studio\u002Flexicon\u002Fbase.py`)\n\n**output_coords:** Use `handshake_dim`\u002F`handshake_coords` for input validation, then increment `lead_time`. Prefer a shared coordinate-check helper and call it from `output_coords`, `__call__`, and iterator setup before model execution.\n\n### Step 5 — Implement Forward Pass\n\n**`__call__`:** @batch_func decorated, shape (batch, time, lead_time, var, lat, lon).\nReshape to model format → call model → reshape back.\n\n**`create_iterator`:** MUST yield initial condition first (step 0).\nUse `front_hook`\u002F`rear_hook` for perturbation injection.\n\n### Step 6 — Implement Model Loading\n\n**`load_default_package`:** Lock HuggingFace URLs: `hf:\u002F\u002Forg\u002Frepo@commit`\n\n**`load_model`:** Use `package.resolve()`, `map_location=\"cpu\"`, `eval()` mode,\ndecorate with `@check_optional_dependencies()`.\n\n### Step 7 — Write Tests\n\n**File:** `test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py`\n\n**Required tests:**\n| Function | Purpose |\n|----------|---------|\n| `test_\u003Cmodel>_call` | Single forward pass (parametrize device\u002Ftime) |\n| `test_\u003Cmodel>_iter` | Iterator produces sequence |\n| `test_\u003Cmodel>_exceptions` | Invalid coords raise errors |\n| `test_\u003Cmodel>_package` | Real weights (`@pytest.mark.package`) |\n\nCreate `PhooModelName` dummy matching interface for mock tests.\n\n**Run tests:**\n```bash\nuv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py -m \"not package\" -v\nuv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py::test_\u003Cmodel>_package --package -v\n```\n\nDo not omit the package test. If arbitrary random inputs are not physically\nvalid for the real checkpoint, use a stable model-appropriate synthetic input\nwhile still loading real weights and running a forward pass.\n\n### Step 8 — Register Model (if requested)\n\n- Add to `earth2studio\u002Fmodels\u002Fpx\u002F__init__.py` (alphabetical)\n- Verify deps in pyproject.toml\n\n### Step 9 — Documentation\n\n- Add to `docs\u002Fmodules\u002Fmodels_px.rst` (alphabetical). This is required for\n  every new prognostic model so the API docs include the generated page.\n- Add to `docs\u002Fuserguide\u002Fabout\u002Finstall.md` (alphabetical tab) for the\n  model extra, even when the extra is empty. Include model-specific notes plus\n  both `pip install earth2studio[model-name]` and\n  `uv add earth2studio --extra model-name` instructions.\n- Update `CHANGELOG.md` under `### Added`. This is required for every new\n  prognostic model.\n\n**Format and lint:**\n```bash\nmake format && make lint && make license\n```\n\n### Step 10 - Validation (if requested)\n\nFollow `references\u002Fvalidation-guide.md`. Create uncommitted vanilla, E2S,\ncomparison, and sanity-check scripts; do not commit generated outputs or images.\nUse PR-safe placeholders for plots so the user can upload images manually.\n\n**[CONFIRM]** User must visually inspect plots before proceeding.\n\n### Step 11 - PR (if requested)\n\nFollow `references\u002Fvalidation-guide.md` and use:\n- `references\u002Fpr-body-template.md`\n- `references\u002Fpr-comment-template.md`\n\nBefore creating the PR, verify `pyproject.toml` has the model extra, the\n`all` extra includes it, install docs include both pip and uv commands, and\n`docs\u002Fmodules\u002Fmodels_px.rst` plus `CHANGELOG.md` are updated.\n\nDo not include machine names, absolute paths, device inventory, or uploaded image\nlinks in PR text. Use plot placeholders instead.\n\n---\n\n## Examples\n\n### Simple Identity Model\n```text\nUser: Create IdentityModel - returns input unchanged, 6h step, 181x360, vars: t2m, u10m, v10m, msl\n\nAgent: [reads SKILL.md, creates identity.py with triple inheritance,\n        creates test_identity.py, runs pytest, runs make format && lint]\n```\n\n### External Model (Pangu)\n```text\nUser: Add Pangu-Weather wrapper\n      GitHub: https:\u002F\u002Fgithub.com\u002F198808xc\u002FPangu-Weather\n\nAgent: [reads SKILL.md, fetches inference.py, creates pangu.py,\n        creates test_pangu.py, runs pytest]\n```\n\n---\n\n## Key Patterns\n\n### Coordinate Template\n```python\n@property\ndef input_coords(self) -> CoordSystem:\n    return CoordSystem({\n        \"batch\": np.empty(0),\n        \"time\": np.empty(0),\n        \"lead_time\": np.array([np.timedelta64(0, \"h\")]),\n        \"variable\": np.array([\"t2m\", \"u10m\", ...]),\n        # Public Earth2Studio convention is north-to-south latitude.\n        \"lat\": np.linspace(90, -90, 181),\n        \"lon\": np.linspace(0, 359, 360),\n    })\n\n@batch_coords()\ndef output_coords(self, input_coords: CoordSystem) -> CoordSystem:\n    output = input_coords.copy()\n    output[\"lead_time\"] = input_coords[\"lead_time\"] + np.timedelta64(6, \"h\")\n    return output\n```\n\n### Iterator Template\n```python\ndef create_iterator(self, x, coords):\n    yield x, coords  # Initial condition (step 0)\n    while True:\n        x, coords = self.front_hook(x, coords)\n        x, coords = self(x, coords)\n        x, coords = self.rear_hook(x, coords)\n        yield x, coords\n```\n\n---\n\n## Troubleshooting\n\n| Error | Solution |\n|-------|----------|\n| `OptionalDependencyFailure` | `uv add --optional \u003Cgroup> \u003Cpkg>` |\n| Coordinate handshake fails | Check `handshake_dim` indices match dim position |\n| Iterator wrong shapes | Debug reshape logic with random input |\n| `ModuleNotFoundError: pytest` | Use `uv run pytest` not `pytest` |\n\n---\n\n## Reminders\n\n**DO:**\n- Use `uv run python` for ALL Python commands\n- Use `loguru.logger`, never `print()`\n- Inherit `torch.nn.Module + AutoModelMixin + PrognosticMixin`\n- Yield initial condition first in `create_iterator`\n- Use `front_hook()`\u002F`rear_hook()` in `_default_generator`\n- Include SPDX header in every .py file\n\n**DON'T:**\n- Create general base classes for reuse\n- Commit API keys or comparison scripts\n- Read from `evals\u002Ftargets\u002F`\n","## Quick Start Checklist\n\n**Do these steps IN ORDER. Do not skip any step.**\n\n- [ ] Read this SKILL.md completely first\n- [ ] Get reference script (Step 0)\n- [ ] Create `earth2studio\u002Fmodels\u002Fpx\u002F\u003Cname>.py` with triple inheritance\n- [ ] Create `test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py` with mock tests\n- [ ] Run: `uv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py -v`\n- [ ] Add\u002Fupdate model extra, install docs, API docs, and changelog (Steps 1-2, 9)\n- [ ] Run: `make format && make lint`\n\n> **⚠️ CRITICAL:** Always use `uv run` for Python commands:\n> - ✅ `uv run pytest ...` \u002F `uv run python ...`\n> - ❌ `pytest ...` \u002F `python ...` (missing dependencies)\n>\n> **Stuck or wrong output:** Do not keep retrying the same fix. Follow\n> [Self-Improvement](#self-improvement) to patch this skill before continuing.\n\n## Purpose\n\nImplement a prognostic model wrapper connecting third-party ML weather models\nto Earth2Studio. Prognostic models time-integrate forward—given initial state,\nthey predict future states by stepping through time (e.g., 6-hour increments).\n\n## Workspace\n\n| Context | Location |\n|---------|----------|\n| Harbor eval | Write to `\u002Fworkspace\u002Foutput\u002Fearth2studio\u002Fmodels\u002Fpx\u002F...` |\n| Harbor + `--copy-repo` | Full checkout at `\u002Fworkspace\u002Frepo` |\n| Local clone | Directory with `pyproject.toml` |\n\n**Never read `evals\u002Ftargets\u002F`** — grader references only.\n\n### Reference Files\n\nLoad on demand during the matching step:\n\n| File | Content | Load at |\n|------|---------|---------|\n| `references\u002Fskeleton-template.py` | Full model skeleton with FILL comments | Steps 3–6 |\n| `references\u002Fmethod-templates.py` | Canonical method implementations | Steps 4–6 |\n| `references\u002Ftesting-guide.py` | Test skeleton and mock patterns | Step 7 |\n| `references\u002Fvalidation-guide.md` | Comparison scripts, PR, code review | Steps 10–11 |\n\n---\n\n## Workflow Steps\n\n### Step 0 — Get Reference Script\n\nIf `$ARGUMENTS` provided, use it. Otherwise ask:\n> Please provide a reference inference script URL\u002Fpath.\n\n### Step 1 — Analyze & Propose Dependencies\n\nAnalyze: packages, architecture, I\u002FO shapes, time step, resolution, checkpoint.\n\nPropose `pyproject.toml` group (alphabetical, add to `all`). Every\nprognostic model must have an optional dependency extra, even when no packages\nare required:\n```toml\nmodel-name = [\"package1>=version\", \"package2\"]\n# or, when no additional packages are required:\nmodel-name = []\n```\n\n**[CONFIRM]** Present dependencies and ask user to approve.\n\n### Step 2 — Add Dependencies\n\nEdit `pyproject.toml`: add the model extra alphabetically, even if it is\nempty, and update the `all` aggregate.\n\n### Step 3 — Create Model File\n\n**File:** `earth2studio\u002Fmodels\u002Fpx\u002F\u003Clowercase>.py`\n\n**Required inheritance (all three):**\n```python\nclass ModelName(torch.nn.Module, AutoModelMixin, PrognosticMixin):\n```\n\n**Required imports:**\n```python\nimport numpy as np\nimport torch\nfrom earth2studio.models.auto import AutoModelMixin, Package\nfrom earth2studio.models.batch import batch_coords, batch_func\nfrom earth2studio.models.px.base import PrognosticMixin\nfrom earth2studio.models.utils import create_coords_from_lat_lon, handshake_dim\nfrom earth2studio.lexicon import E2STUDIO_VOCAB\nfrom earth2studio.utils import check_optional_dependencies\nfrom loguru import logger\n```\n\n**SPDX header (required at top of every .py file):**\n```python\n# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES.\n# SPDX-License-Identifier: Apache-2.0\n```\n\n**Canonical method order:**\n1. `__init__` 2. `input_coords` 3. `output_coords` (@batch_coords)\n4. `load_default_package` 5. `load_model` 6. `to` (optional)\n7. Private methods 8. `__call__` (@batch_func) 9. `_default_generator`\n10. `create_iterator`\n\n### Step 4 — Implement Coordinates\n\n**input_coords rules:**\n- `batch`: `np.empty(0)`\n- `time`: `np.empty(0)` (dynamic)\n- `lead_time`: starts at `np.timedelta64(0, \"h\")`\n- `lat`: 90 to -90 (north to south); this is the public Earth2Studio convention even if the source model uses the opposite order\n- `lon`: 0 to 360\n- If a checkpoint\u002Fmodel core expects south-to-north latitude, flip tensors internally before\u002Fafter the core model; do not expose flipped latitude in `input_coords` or `output_coords`\n- Map variables to `E2STUDIO_VOCAB` (282 entries in `earth2studio\u002Flexicon\u002Fbase.py`)\n\n**output_coords:** Use `handshake_dim`\u002F`handshake_coords` for input validation, then increment `lead_time`. Prefer a shared coordinate-check helper and call it from `output_coords`, `__call__`, and iterator setup before model execution.\n\n### Step 5 — Implement Forward Pass\n\n**`__call__`:** @batch_func decorated, shape (batch, time, lead_time, var, lat, lon).\nReshape to model format → call model → reshape back.\n\n**`create_iterator`:** MUST yield initial condition first (step 0).\nUse `front_hook`\u002F`rear_hook` for perturbation injection.\n\n### Step 6 — Implement Model Loading\n\n**`load_default_package`:** Lock HuggingFace URLs: `hf:\u002F\u002Forg\u002Frepo@commit`\n\n**`load_model`:** Use `package.resolve()`, `map_location=\"cpu\"`, `eval()` mode,\ndecorate with `@check_optional_dependencies()`.\n\n### Step 7 — Write Tests\n\n**File:** `test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py`\n\n**Required tests:**\n| Function | Purpose |\n|----------|---------|\n| `test_\u003Cmodel>_call` | Single forward pass (parametrize device\u002Ftime) |\n| `test_\u003Cmodel>_iter` | Iterator produces sequence |\n| `test_\u003Cmodel>_exceptions` | Invalid coords raise errors |\n| `test_\u003Cmodel>_package` | Real weights (`@pytest.mark.package`) |\n\nCreate `PhooModelName` dummy matching interface for mock tests.\n\n**Run tests:**\n```bash\nuv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py -m \"not package\" -v\nuv run pytest test\u002Fmodels\u002Fpx\u002Ftest_\u003Cname>.py::test_\u003Cmodel>_package --package -v\n```\n\nDo not omit the package test. If arbitrary random inputs are not physically\nvalid for the real checkpoint, use a stable model-appropriate synthetic input\nwhile still loading real weights and running a forward pass.\n\n### Step 8 — Register Model (if requested)\n\n- Add to `earth2studio\u002Fmodels\u002Fpx\u002F__init__.py` (alphabetical)\n- Verify deps in pyproject.toml\n\n### Step 9 — Documentation\n\n- Add to `docs\u002Fmodules\u002Fmodels_px.rst` (alphabetical). This is required for\n  every new prognostic model so the API docs include the generated page.\n- Add to `docs\u002Fuserguide\u002Fabout\u002Finstall.md` (alphabetical tab) for the\n  model extra, even when the extra is empty. Include model-specific notes plus\n  both `pip install earth2studio[model-name]` and\n  `uv add earth2studio --extra model-name` instructions.\n- Update `CHANGELOG.md` under `### Added`. This is required for every new\n  prognostic model.\n\n**Format and lint:**\n```bash\nmake format && make lint && make license\n```\n\n### Step 10 - Validation (if requested)\n\nFollow `references\u002Fvalidation-guide.md`. Create uncommitted vanilla, E2S,\ncomparison, and sanity-check scripts; do not commit generated outputs or images.\nUse PR-safe placeholders for plots so the user can upload images manually.\n\n**[CONFIRM]** User must visually inspect plots before proceeding.\n\n### Step 11 - PR (if requested)\n\nFollow `references\u002Fvalidation-guide.md` and use:\n- `references\u002Fpr-body-template.md`\n- `references\u002Fpr-comment-template.md`\n\nBefore creating the PR, verify `pyproject.toml` has the model extra, the\n`all` extra includes it, install docs include both pip and uv commands, and\n`docs\u002Fmodules\u002Fmodels_px.rst` plus `CHANGELOG.md` are updated.\n\nDo not include machine names, absolute paths, device inventory, or uploaded image\nlinks in PR text. Use plot placeholders instead.\n\n---\n\n## Examples\n\n### Simple Identity Model\n```text\nUser: Create IdentityModel - returns input unchanged, 6h step, 181x360, vars: t2m, u10m, v10m, msl\n\nAgent: [reads SKILL.md, creates identity.py with triple inheritance,\n        creates test_identity.py, runs pytest, runs make format && lint]\n```\n\n### External Model (Pangu)\n```text\nUser: Add Pangu-Weather wrapper\n      GitHub: https:\u002F\u002Fgithub.com\u002F198808xc\u002FPangu-Weather\n\nAgent: [reads SKILL.md, fetches inference.py, creates pangu.py,\n        creates test_pangu.py, runs pytest]\n```\n\n---\n\n## Key Patterns\n\n### Coordinate Template\n```python\n@property\ndef input_coords(self) -> CoordSystem:\n    return CoordSystem({\n        \"batch\": np.empty(0),\n        \"time\": np.empty(0),\n        \"lead_time\": np.array([np.timedelta64(0, \"h\")]),\n        \"variable\": np.array([\"t2m\", \"u10m\", ...]),\n        # Public Earth2Studio convention is north-to-south latitude.\n        \"lat\": np.linspace(90, -90, 181),\n        \"lon\": np.linspace(0, 359, 360),\n    })\n\n@batch_coords()\ndef output_coords(self, input_coords: CoordSystem) -> CoordSystem:\n    output = input_coords.copy()\n    output[\"lead_time\"] = input_coords[\"lead_time\"] + np.timedelta64(6, \"h\")\n    return output\n```\n\n### Iterator Template\n```python\ndef create_iterator(self, x, coords):\n    yield x, coords  # Initial condition (step 0)\n    while True:\n        x, coords = self.front_hook(x, coords)\n        x, coords = self(x, coords)\n        x, coords = self.rear_hook(x, coords)\n        yield x, coords\n```\n\n---\n\n## Troubleshooting\n\n| Error | Solution |\n|-------|----------|\n| `OptionalDependencyFailure` | `uv add --optional \u003Cgroup> \u003Cpkg>` |\n| Coordinate handshake fails | Check `handshake_dim` indices match dim position |\n| Iterator wrong shapes | Debug reshape logic with random input |\n| `ModuleNotFoundError: pytest` | Use `uv run pytest` not `pytest` |\n\n---\n\n## Reminders\n\n**DO:**\n- Use `uv run python` for ALL Python commands\n- Use `loguru.logger`, never `print()`\n- Inherit `torch.nn.Module + AutoModelMixin + PrognosticMixin`\n- Yield initial condition first in `create_iterator`\n- Use `front_hook()`\u002F`rear_hook()` in `_default_generator`\n- Include SPDX header in every .py file\n\n**DON'T:**\n- Create general base classes for reuse\n- Commit API keys or comparison scripts\n- Read from `evals\u002Ftargets\u002F`\n",{"name":5,"license":15,"version":44,"metadata":45,"description":50,"argument-hint":51},"0.16.0",{"tags":46,"author":49},[47,48,25],"earth2studio","prognostic-model","NVIDIA Earth-2 Team \u003Cagent-skills@nvidia.com>","Create Earth2Studio prognostic (time-stepping forecast) model wrappers. Do NOT use for diagnostic models, data sources, or installation.\n","URL or local path to reference inference script (optional)","claude\u002Finstall-gsd-build-foQdV","d86cd127f527124b5fd0fd0bc679a4d79b7d01d7",".agents\u002Fskills\u002Fearth2studio-create-prognostic","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik","https:\u002F\u002Fnorvik-orpin.vercel.app","https:\u002F\u002Fgithub.com\u002Fpattanation","2026-07-17 11:17:04",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add pattanation\u002FNorvik --skill earth2studio-create-prognostic",{"tool":65,"command":66},"bunx","bunx skills add pattanation\u002FNorvik --skill earth2studio-create-prognostic",{"tool":68,"command":69},"pnpm","pnpm dlx skills add pattanation\u002FNorvik --skill earth2studio-create-prognostic","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002FSKILL.md",true,[73,79,83,89,95,99,103,107,111,115,119,123,127,131,135,139,143],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"BENCHMARK.md","REFERENCE","参考文档",4385,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002FBENCHMARK.md",{"path":80,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":81,"sourceHtmlUrl":82},"evals\u002Fconfig.yml",1175,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Fconfig.yml",{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"evals\u002Fenvironment\u002FDockerfile","OTHER","其他",1433,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Fenvironment\u002FDockerfile",{"path":90,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":93,"sourceHtmlUrl":94},"evals\u002Fenvironment\u002Fsetup\u002Fbootstrap.sh","SCRIPT","脚本",1226,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Fenvironment\u002Fsetup\u002Fbootstrap.sh",{"path":96,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":97,"sourceHtmlUrl":98},"evals\u002Fevals.json",2491,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Fevals.json",{"path":100,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":101,"sourceHtmlUrl":102},"evals\u002Ftargets\u002Feval_1_target.py",6720,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Ftargets\u002Feval_1_target.py",{"path":104,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":105,"sourceHtmlUrl":106},"evals\u002Ftargets\u002Feval_2_target.py",8484,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Ftargets\u002Feval_2_target.py",{"path":108,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":109,"sourceHtmlUrl":110},"evals\u002Ftargets\u002Ftest\u002Feval_1_test_target.py",5693,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Ftargets\u002Ftest\u002Feval_1_test_target.py",{"path":112,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":113,"sourceHtmlUrl":114},"evals\u002Ftargets\u002Ftest\u002Feval_2_test_target.py",6567,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fevals\u002Ftargets\u002Ftest\u002Feval_2_test_target.py",{"path":116,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":117,"sourceHtmlUrl":118},"references\u002Fmethod-templates.py",12915,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Fmethod-templates.py",{"path":120,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":121,"sourceHtmlUrl":122},"references\u002Fpr-body-template.md",2496,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Fpr-body-template.md",{"path":124,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":125,"sourceHtmlUrl":126},"references\u002Fpr-comment-template.md",2217,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Fpr-comment-template.md",{"path":128,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":129,"sourceHtmlUrl":130},"references\u002Fskeleton-template.py",15570,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Fskeleton-template.py",{"path":132,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":133,"sourceHtmlUrl":134},"references\u002Ftesting-guide.py",14061,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Ftesting-guide.py",{"path":136,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":137,"sourceHtmlUrl":138},"references\u002Fvalidation-guide.md",4935,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Freferences\u002Fvalidation-guide.md",{"path":140,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":141,"sourceHtmlUrl":142},"skill-card.md",2493,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fskill-card.md",{"path":144,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":145,"sourceHtmlUrl":146},"skill.oms.sig",7301,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fearth2studio-create-prognostic\u002Fskill.oms.sig",[148,180,205,229,251,266],{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":152,"sourceHtmlUrl":153,"categories":154,"keywords":163,"publishedAt":179},"01M71QDV4DM8T19HEHWATEF1K4","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[155,160],{"categoryNo":156,"categoryName":157,"taxonomyType":158,"taxonomyTypeDesc":159},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},"01JBSEEDCAT000000000000009","前端开发",[164,165,166,26,167,35,168,169,170,171,172,173,174,175,176,177,178],"webapp","testing","webapp testing","applications","frontend","debugging","toolkit","logs","browser","with","playwright","web","behavior","ui","screenshots","2026-11-10 13:02:02",{"skillNo":181,"name":182,"nameZh":6,"description":183,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":184,"sourceHtmlUrl":185,"categories":186,"keywords":188,"publishedAt":179},"01M71QDH2GGMXGA9105C9W1N7B","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FSKILL.md",[187],{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},[189,190,191,175,192,193,194,26,195,196,168,197,23,198,199,200,201,202,203,204],"builder","artifacts builder","artifacts","web artifacts builder","single-file","css","Tailwind","ui components","single","file","components","react","multi","state","routing","state management",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":209,"licenseFileUrl":210,"sourceHtmlUrl":211,"categories":212,"keywords":214,"publishedAt":179},"01M71QD9T2XC3EWMQNN9ACNWQ1","vueuse-functions","Apply VueUse composables where appropriate to build concise, maintainable Vue.js \u002F Nuxt features.","MIT","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FSKILL.md",[213],{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},[215,216,217,218,219,220,221,222,223,224,225,226,227,228],"functions","vueuse","vueuse functions","project","nuxt","apply","github","concise","build","https","features","vue","js","composables",{"skillNo":230,"name":231,"nameZh":6,"description":232,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":209,"licenseFileUrl":233,"sourceHtmlUrl":234,"categories":235,"keywords":238,"publishedAt":179},"01M71QD51HWSGYMCMB7RW7PGK8","vue-testing-best-practices","Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FSKILL.md",[236,237],{"categoryNo":156,"categoryName":157,"taxonomyType":158,"taxonomyTypeDesc":159},{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},[239,165,240,226,241,174,242,243,244,221,245,26,246,247,248,23,249,227,250],"vue testing best practices","testing best practices","best practices","test","testing patterns","component","vitest","mocking","e2e","utils","patterns","e2e testing",{"skillNo":252,"name":253,"nameZh":6,"description":254,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":209,"licenseFileUrl":255,"sourceHtmlUrl":256,"categories":257,"keywords":259,"publishedAt":179},"01M71QD358H2DJ9THJRBP77T3T","vue-router-best-practices","Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FSKILL.md",[258],{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},[260,226,261,241,262,244,263,221,249,264,265],"router","vue router best practices","route","guards","navigation","lifecycle",{"skillNo":267,"name":268,"nameZh":6,"description":269,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":209,"licenseFileUrl":270,"sourceHtmlUrl":271,"categories":272,"keywords":274,"publishedAt":179},"01M71QCYPNWDE2MQZ1TF3ED5S4","vue-best-practices","MUST be used for Vue.js tasks. Strongly recommends Composition API with `\u003Cscript setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FSKILL.md",[273],{"categoryNo":161,"categoryName":162,"taxonomyType":158,"taxonomyTypeDesc":159},[275,226,241,276,218,277,278,279,260,280,281,282,283,284,285,26,286,23,287,288],"vue best practices","Composition","files","tasks","api","pinia","work","options","ssr","typescript","as","vite","load","standard"]