[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71PTGN1ZFDBJQMP4QBN013P":3,"skill-same:01M71PTGN1ZFDBJQMP4QBN013P":142},{"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":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":59,"commitSha":60,"skillDirectory":61,"forksCount":14,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":65,"install":66,"resources":79},"01M71PTGN1ZFDBJQMP4QBN013P","tao-analyze-gaps-visual-changenet",null,"Performs gap analysis on NVIDIA TAO VCN Classify (Visual Component Net) experiments by invoking the data-services container (`tao_toolkit.data_services` from `versions.yaml`) directly via `docker run … gap_analysis vcn_aoi …` — picks the optimal decision threshold, ranks per-sample weakness, and emits a top-K weakest parquet expanded per-lighting for downstream augmentation. Use when analyzing VCN classification failures, picking SDA augmentation targets, or auditing PASS\u002FNO_PASS boundary cases.","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\u002Ftao-analyze-gaps-visual-changenet\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"tao","visual","gaps","changenet","tao analyze gaps visual changenet","analyze","bank","read","at","run","classify","top","component","sample","analysis","Bash","image","when","sda","decision","2026-11-10 13:02:02",false,"---\nname: tao-analyze-gaps-visual-changenet\ndescription: Performs gap analysis on NVIDIA TAO VCN Classify (Visual Component Net) experiments by invoking the data-services container (`tao_toolkit.data_services` from `versions.yaml`) directly via `docker run … gap_analysis vcn_aoi …` — picks the optimal decision threshold, ranks per-sample weakness, and emits a top-K weakest parquet expanded per-lighting for downstream augmentation. Use when analyzing VCN classification failures, picking SDA augmentation targets, or auditing PASS\u002FNO_PASS boundary cases.\nlicense: Apache-2.0\ncompatibility: Requires docker + nvidia-container-toolkit and a CUDA GPU. Pulls the `tao_toolkit.data_services` image declared in `versions.yaml` at the skill bank root.\nmetadata:\n  author: NVIDIA Corporation\n  version: \"0.1.0\"\nallowed-tools: Read Bash\ntags:\n- data\n- rca\n- vcn\n- aoi\n---\n\n# TAO VCN Classify Gap Analysis Skill\n\nYou are an analyst for NVIDIA TAO VCN Classify (Visual Component Net) inference results. Your job is to identify the **weakest samples per ground-truth label** by measuring signed distance from the decision threshold *in the wrong direction*, then surface them for downstream augmentation or relabeling.\n\nThis skill is intentionally lightweight. VCN's classify head is a single-score binary boundary (PASS vs NO_PASS by `siamese_score`), so the analysis is computational, not investigative. The whole computation lives behind one direct `docker run` invocation against the `tao_toolkit.data_services` image declared in `versions.yaml` (resolved at runtime — see Setup). The container's entrypoint takes `\u003Ccategory> \u003Caction> [hydra overrides...]`; we pass `gap_analysis vcn_aoi key=value …`. Each override is a bare Hydra `key=value` that selectively overrides the script's `GapAnalysisConfig` schema (defaults are baked into the container; introspect with `docker run ... gap_analysis vcn_aoi --cfg=job`). (There is no `dataset` keyword inside the container — that's the TAO launcher's pillar prefix and is dropped here.) You do **not** need delegated analysis, multi-phase image audits, or component-type clustering — VCN does not expose those dimensions. View only a small set of representative weak samples to qualify the gaps after the container returns.\n\nCLI surface can shift between data-services container builds. If a `gap_analysis vcn_aoi` invocation fails on argument parsing, introspect the actual schema once per image with `docker run --rm \"$DS_IMAGE\" gap_analysis vcn_aoi --cfg=job` and reconcile any renamed keys (e.g. `inference_csv` vs `inference_results_dir`, `output_dir` vs `results_dir`) before retrying. Output parquet name is `kpi_gaps.parquet`.\n\n---\n\n## Inputs\n\n1. **Experiment result directory** — contains `inference\u002Finference.csv` from TAO VCN Classify inference. Required columns: `input_path`, `object_name`, `label`, `siamese_score`. Pass the **directory** (e.g. `inference\u002Flatest\u002F`), not the CSV file — the container reads `inference_results_dir\u002Finference.csv`.\n2. **Training code\u002Fconfig directory** — contains the VCN train YAML. The container reads `dataset.classify.input_map` (lighting condition list) and `dataset.classify.image_ext` from it to expand each weak sample into one row per lighting.\n3. **Dataset directory** — image root prepended to the relative `input_path` from each row (`kpi_media_path`).\n4. **Schema overrides** — `min_recall`, `top_k_per_label`, and optionally a hard-pinned `threshold` are passed as Hydra overrides (defaults: `min_recall=1.0`, `top_k_per_label=50`, `threshold=-1.0` meaning sweep). **`top_k_per_label` must be a positive integer** — omitting it flips the container into \"below-threshold filter\" mode, which at `min_recall=1.0` returns only PASS misclassifications and zero NO_PASS rows. See Common pitfalls.\n\n---\n\n## Setup\n\nThe threshold sweep, weakness ranking, and per-lighting expansion all run inside the `tao_toolkit.data_services` image declared in `versions.yaml`. Resolve the concrete URI once at the top of the run, then confirm Docker, the NVIDIA container toolkit, and a GPU are present and ensure the image is cached:\n\n```bash\n# Resolve tao_toolkit.data_services → concrete nvcr.io\u002F... URI from versions.yaml\nDS_IMAGE=$(python3 -c \"import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'\u002Fversions.yaml'))['images']['tao_toolkit']['data_services'])\")\necho \"DS_IMAGE=$DS_IMAGE\"\n\ndocker info > \u002Fdev\u002Fnull && echo \"OK: docker\"\nnvidia-smi > \u002Fdev\u002Fnull && echo \"OK: GPU\"\ndocker image inspect \"$DS_IMAGE\" > \u002Fdev\u002Fnull \\\n  || docker pull \"$DS_IMAGE\"\n```\n\n`TAO_SKILL_BANK_PATH` is usually exported by the installed skill bank. If it is unset, point it at the skill-bank repo root before resolving. A GPU is required; aborting early on a GPU-less host saves a confusing late error.\n\nThree setup rules are load-bearing and easy to get wrong:\n\n- **Path mounting** — every host path the container reads or writes (`inference.csv`, train YAML, dataset image root, output dir) must be bind-mounted, simplest with `-v $WORKSPACE:$WORKSPACE -w $WORKSPACE` so absolute paths resolve identically on both sides.\n- **Do not pass `--user $(id -u):$(id -g)`** — it triggers `KeyError: 'getpwuid(): uid not found: \u003Cuid>'` during the container's `transformers` import; `chown` outputs back to the host UID afterwards instead.\n- **`-e \u003Cspec>` is required, not optional** — current images hard-require it and exit with `ValueError: The subtask vcn_aoi requires the following argument: -e\u002F--experiment_spec_file` before parsing CLI overrides.\n\nSee `references\u002Fcontainer-setup.md` for the full path-mounting pattern, the `--user`\u002F`chown` rationale and `alpine` chown command, multi-`-v` guidance, and the `-e \u003Cspec>` requirement detail.\n\n---\n\n## Method\n\nThe whole skill is a single `docker run` invocation followed by a small visual spot-check. The container does Steps 1–4 internally (threshold sweep, weakness scoring, top-K selection, per-lighting expansion). You handle Step 5 (visual spot-check) directly with the Read tool.\n\n### Step 1–4 — Run the container\n\n```bash\n$DOCKER gap_analysis vcn_aoi \\\n    inference_results_dir=\u003Cexp_dir>\u002Finference\u002F\u003Clabel>\u002F \\\n    train_config=\u003Cexp_dir>\u002Ftrain.yaml \\\n    kpi_media_path=\u003Cdataset_root> \\\n    results_dir=\u003Crca_results_dir> \\\n    top_k_per_label=50\n```\n\n> **Always pass `top_k_per_label`.** This is the argument that switches the container\n> from the default \"samples below threshold\" filter into proper top-K-per-label\n> ranking. At `min_recall=1.0` the threshold is by construction at-or-below every\n> NO_PASS score, so the below-threshold filter returns ONLY misclassified PASS rows\n> and zero NO_PASS rows — useless as an augmentation queue. With `top_k_per_label`\n> set to a positive integer (either in the spec or as a Hydra override), the\n> container computes signed weakness against the threshold for every row and\n> surfaces the K weakest **per ground-truth label**, which is the per-label ranked\n> output downstream steps consume.\n\nReads `inference.csv`, sweeps every unique `siamese_score` plus one value just below the minimum, keeps the candidates with NO_PASS-class recall ≥ `min_recall` (with `1e-12` tolerance), then picks the threshold with the best F1 (tie-break: precision, then threshold value). For every row, computes signed weakness from that threshold (positive = misclassified, negative = correct, magnitude = margin). Sorts by weakness descending and takes the top `top_k_per_label` per ground-truth label, then expands each weak row into one row per lighting condition using `dataset.classify.input_map` and `dataset.classify.image_ext` from the train YAML.\n\nIf **no** candidate threshold meets the recall target, the container exits non-zero and writes `unreachable_kpi.txt` into `results_dir` explaining which recall the model can actually achieve. In that case, stop the analysis after the docker call, write a one-section report explaining the model fundamentally cannot reach the KPI at any operating point, and recommend retraining or relabeling — skip the visual spot-check.\n\n**Container writes into `results_dir`:**\n\n| Artifact | Contents |\n|----------|----------|\n| `kpi_gaps.parquet` | Top-K weakest per label, expanded per lighting. Columns: `filepath`, `label`, `siamese_score`, `weakness`. |\n| `threshold.txt` | Chosen decision threshold (single float, plain text). |\n| `metrics.json` | At the chosen threshold: `precision`, `recall`, `f1`, confusion matrix `{tp, fp, tn, fn}`, plus per-label `{total, mean_weakness, median_weakness, max_weakness, n_misclassified}`. |\n| `weak_samples_breakdown.txt` | Per-label kept-row breakdown: `\u003Ccount>` total, `\u003C%>` of all kept rows, `N` misclassified (weakness > 0), `N` marginal (weakness ≤ 0). |\n| `unreachable_kpi.txt` | Only written when the recall target is unreachable. Presence of this file means: skip Step 5, write the abridged report, recommend retrain. |\n\nPrint the container's stdout summary (chosen threshold, kept-row counts, per-label breakdown) to your own stdout so the script-check hook can verify the run produced output.\n\n### Step 5 — Visual spot check (small, fixed)\n\nSkip this step if `unreachable_kpi.txt` exists. Otherwise use the Read tool to **view** the 5 weakest PASS samples and the 5 weakest NO_PASS samples from `kpi_gaps.parquet` (deduplicated to one row per sample, using the FIRST-lighting `filepath`), classify each as exactly one of **mislabeled** \u002F **edge case** \u002F **data quality** \u002F **systematic**, and copy each viewed image (resized to 128×128 if PIL is available, otherwise just copy) into `\u003Cresults_dir>\u002Frca_images\u002F`. This is the only image inspection required — do not view dozens of images, run failure mode clustering, or audit goldens (VCN has no golden images).\n\nSee `references\u002Fvisual-spot-check.md` for the exact sample-selection sort, the per-lighting deduplication rule, the full definition of each verdict category, and the image-copy detail.\n\n---\n\n## Reference invocation\n\nPaste-and-edit the workspace, the four paths, and the two numeric knobs; this runs end-to-end. Capture stdout so the script-check hook sees row counts.\n\n```bash\nWORKSPACE=\u003Cabsolute path>            # mounted identically inside the container\nEXP_DIR=\u003Cexperiment_result_dir>      # contains inference\u002Finference.csv and train.yaml; must be inside $WORKSPACE\nDATASET_ROOT=\u003Cdataset_root>          # image root for inference.csv input_path entries; must be inside $WORKSPACE\nMIN_RECALL=1.0                       # zero-miss default; lower if KPI relaxes\nTOP_K=50                             # per-label augmentation budget\nOUT=\"$EXP_DIR\u002Frca_results\u002F$(date +%Y-%m-%d_%H%M%S)\"\nSPEC=\"$OUT\u002Fvcn_aoi_spec.yaml\"\nIMG=$(python3 -c \"import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'\u002Fversions.yaml'))['images']['tao_toolkit']['data_services'])\")\n\nmkdir -p \"$OUT\"\n\n# Write the gap-analysis spec for this run\ncat > \"$SPEC\" \u003C\u003CEOF\nmin_recall: $MIN_RECALL\ntop_k_per_label: $TOP_K\nEOF\n\ndocker run --gpus all --rm --ipc=host \\\n    -v \"$WORKSPACE:$WORKSPACE\" -w \"$WORKSPACE\" \\\n    \"$IMG\" gap_analysis vcn_aoi \\\n    -e \"$SPEC\" \\\n    inference_results_dir=\"$EXP_DIR\u002Finference\u002Flatest\u002F\" \\\n    train_config=\"$EXP_DIR\u002Ftrain.yaml\" \\\n    kpi_media_path=\"$DATASET_ROOT\" \\\n    results_dir=\"$OUT\"\n\n# Container writes as root with --user dropped; chown back to host UID if needed.\ndocker run --rm -v \"$WORKSPACE:\u002Fw\" alpine chown -R \"$(id -u):$(id -g)\" \"\u002Fw\u002F$(realpath --relative-to=\"$WORKSPACE\" \"$OUT\")\"\n\n# Sanity print so the script-check hook sees real numbers\npython3 - \"$OUT\" \u003C\u003C 'PYEOF'\nimport json, os, sys\nout = sys.argv[1]\nunreachable = os.path.join(out, \"unreachable_kpi.txt\")\nif os.path.isfile(unreachable):\n    print(\"KPI UNREACHABLE — see\", unreachable)\n    sys.exit(0)\nwith open(os.path.join(out, \"threshold.txt\")) as f:\n    print(\"threshold:\", f.read().strip())\nwith open(os.path.join(out, \"metrics.json\")) as f:\n    m = json.load(f)\nprint(f\"precision={m['precision']:.4f} recall={m['recall']:.4f} f1={m['f1']:.4f}\")\nimport pandas as pd\ndf = pd.read_parquet(os.path.join(out, \"kpi_gaps.parquet\"))\nprint(f\"kpi_gaps.parquet: rows={len(df)}, cols={list(df.columns)}\")\nprint(df['label'].value_counts())\nPYEOF\n```\n\n---\n\n## Outputs\n\nWrite everything into a timestamped folder under the experiment result directory. The container's outputs go straight there; the visual spot-check writes `rca_images\u002F`; any runtime packaging hook may add session\u002Fconfig capture artifacts after `RCA_Report.md` is written.\n\n```\n\u003Cexperiment_result_dir>\u002Frca_results\u002FYYYY-MM-DD_HHMMSS\u002F\n├── RCA_Report.md              # Full gap analysis report (you write this)\n├── kpi_gaps.parquet           # Container: top-K weakest per label, expanded per lighting\n├── threshold.txt              # Container: chosen decision threshold (single float)\n├── metrics.json               # Container: confusion matrix + per-label distribution stats\n├── weak_samples_breakdown.txt # Container: per-label count\u002Fmisclassified\u002Fmarginal counts\n├── unreachable_kpi.txt        # Container: ONLY when no threshold meets min_recall\n├── rca_images\u002F                # You: thumbnails of the 10 viewed weak samples\n├── rca_config\u002F                # Auto-copied by hook\n└── session log\u002Fartifacts      # Optional, runtime-dependent packaging capture\n```\n\nAt the start of the run, get the real timestamp by running `date +%Y-%m-%d_%H%M%S` in Bash. Do NOT hardcode or guess. If the user specifies a custom output path, use that instead but maintain the same internal structure.\n\n---\n\n## Common pitfalls\n\nThe single most consequential failure mode is **forgetting `top_k_per_label` when `min_recall=1.0`**: at that recall the chosen threshold sits at or below every NO_PASS score, so without `top_k_per_label` the container falls back to a \"samples below threshold\" filter that returns ONLY misclassified PASS rows and zero NO_PASS rows, breaking the augmentation queue. Always include an explicit positive `top_k_per_label` (default 50) in the spec or as a Hydra override.\n\nSee `references\u002Fpitfalls.md` for the complete checklist, covering: forgetting `top_k_per_label`; passing `--user`; calling with only Hydra overrides (no `-e \u003Cspec>`); spec file outside `$WORKSPACE`; spec file with unresolved `???` sentinels; image not pulled \u002F wrong tag; path-mount mismatch; `unreachable_kpi.txt` written; `inference.csv` missing required columns; train YAML missing `dataset.classify.input_map` or `image_ext`; `kpi_media_path` not matching `input_path` prefixes; and no GPU detected from inside the container.\n\n---\n\n## Report Structure\n\nWrite `RCA_Report.md` as a tight (1000–1800 word) computational gap analysis — depth comes from accurate numbers and a clear action list, not narrative. The full report template (7 sections: Verdict, Threshold Selection, Weakness Distribution, Top-K Weakest Samples, Visual Spot Check, Per-Label Breakdown, Recommended Actions — with the confusion-matrix and table layouts) is in `references\u002Foutput-template.md`. When `unreachable_kpi.txt` exists, replace sections 3–6 with a single short section quoting that file's contents and collapse section 7 to one recommendation: retrain or relabel.\n\n---\n\n## Execution Order\n\n1. Resolve `DS_IMAGE` from `versions.yaml` (`images.tao_toolkit.data_services`), then run `docker info`, `nvidia-smi`, and `docker image inspect \"$DS_IMAGE\"` (pulling if missing) once to confirm the environment. Abort with a clear message if any fail.\n2. Run `date +%Y-%m-%d_%H%M%S` to get the timestamp; create `\u003Cexperiment_result_dir>\u002Frca_results\u002F\u003Ctimestamp>\u002F`.\n3. Write `vcn_aoi_spec.yaml` into the timestamped dir with `min_recall` and `top_k_per_label` filled in. Keep it under `$WORKSPACE` so the `-e` path resolves inside the container.\n4. Run `docker run … \"$DS_IMAGE\" gap_analysis vcn_aoi -e vcn_aoi_spec.yaml inference_results_dir=… train_config=… kpi_media_path=… output_dir=…`. The container writes `kpi_gaps.parquet`, `threshold.txt`, `metrics.json`, `weak_samples_breakdown.txt` into `results_dir`. Print the chosen threshold and kept-row counts to stdout so the script-check hook can verify the run produced output.\n5. If `unreachable_kpi.txt` exists, skip Step 6 and write the abridged report. Otherwise continue.\n6. Pick 10 weak samples (5 weakest PASS + 5 weakest NO_PASS) from `kpi_gaps.parquet`, view each test image with Read, classify, and copy each into `rca_images\u002F`.\n7. Write `RCA_Report.md` last — writing it triggers the packaging hook, which copies session logs and skill config alongside.\n","# TAO VCN Classify Gap Analysis Skill\n\nYou are an analyst for NVIDIA TAO VCN Classify (Visual Component Net) inference results. Your job is to identify the **weakest samples per ground-truth label** by measuring signed distance from the decision threshold *in the wrong direction*, then surface them for downstream augmentation or relabeling.\n\nThis skill is intentionally lightweight. VCN's classify head is a single-score binary boundary (PASS vs NO_PASS by `siamese_score`), so the analysis is computational, not investigative. The whole computation lives behind one direct `docker run` invocation against the `tao_toolkit.data_services` image declared in `versions.yaml` (resolved at runtime — see Setup). The container's entrypoint takes `\u003Ccategory> \u003Caction> [hydra overrides...]`; we pass `gap_analysis vcn_aoi key=value …`. Each override is a bare Hydra `key=value` that selectively overrides the script's `GapAnalysisConfig` schema (defaults are baked into the container; introspect with `docker run ... gap_analysis vcn_aoi --cfg=job`). (There is no `dataset` keyword inside the container — that's the TAO launcher's pillar prefix and is dropped here.) You do **not** need delegated analysis, multi-phase image audits, or component-type clustering — VCN does not expose those dimensions. View only a small set of representative weak samples to qualify the gaps after the container returns.\n\nCLI surface can shift between data-services container builds. If a `gap_analysis vcn_aoi` invocation fails on argument parsing, introspect the actual schema once per image with `docker run --rm \"$DS_IMAGE\" gap_analysis vcn_aoi --cfg=job` and reconcile any renamed keys (e.g. `inference_csv` vs `inference_results_dir`, `output_dir` vs `results_dir`) before retrying. Output parquet name is `kpi_gaps.parquet`.\n\n---\n\n## Inputs\n\n1. **Experiment result directory** — contains `inference\u002Finference.csv` from TAO VCN Classify inference. Required columns: `input_path`, `object_name`, `label`, `siamese_score`. Pass the **directory** (e.g. `inference\u002Flatest\u002F`), not the CSV file — the container reads `inference_results_dir\u002Finference.csv`.\n2. **Training code\u002Fconfig directory** — contains the VCN train YAML. The container reads `dataset.classify.input_map` (lighting condition list) and `dataset.classify.image_ext` from it to expand each weak sample into one row per lighting.\n3. **Dataset directory** — image root prepended to the relative `input_path` from each row (`kpi_media_path`).\n4. **Schema overrides** — `min_recall`, `top_k_per_label`, and optionally a hard-pinned `threshold` are passed as Hydra overrides (defaults: `min_recall=1.0`, `top_k_per_label=50`, `threshold=-1.0` meaning sweep). **`top_k_per_label` must be a positive integer** — omitting it flips the container into \"below-threshold filter\" mode, which at `min_recall=1.0` returns only PASS misclassifications and zero NO_PASS rows. See Common pitfalls.\n\n---\n\n## Setup\n\nThe threshold sweep, weakness ranking, and per-lighting expansion all run inside the `tao_toolkit.data_services` image declared in `versions.yaml`. Resolve the concrete URI once at the top of the run, then confirm Docker, the NVIDIA container toolkit, and a GPU are present and ensure the image is cached:\n\n```bash\n# Resolve tao_toolkit.data_services → concrete nvcr.io\u002F... URI from versions.yaml\nDS_IMAGE=$(python3 -c \"import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'\u002Fversions.yaml'))['images']['tao_toolkit']['data_services'])\")\necho \"DS_IMAGE=$DS_IMAGE\"\n\ndocker info > \u002Fdev\u002Fnull && echo \"OK: docker\"\nnvidia-smi > \u002Fdev\u002Fnull && echo \"OK: GPU\"\ndocker image inspect \"$DS_IMAGE\" > \u002Fdev\u002Fnull \\\n  || docker pull \"$DS_IMAGE\"\n```\n\n`TAO_SKILL_BANK_PATH` is usually exported by the installed skill bank. If it is unset, point it at the skill-bank repo root before resolving. A GPU is required; aborting early on a GPU-less host saves a confusing late error.\n\nThree setup rules are load-bearing and easy to get wrong:\n\n- **Path mounting** — every host path the container reads or writes (`inference.csv`, train YAML, dataset image root, output dir) must be bind-mounted, simplest with `-v $WORKSPACE:$WORKSPACE -w $WORKSPACE` so absolute paths resolve identically on both sides.\n- **Do not pass `--user $(id -u):$(id -g)`** — it triggers `KeyError: 'getpwuid(): uid not found: \u003Cuid>'` during the container's `transformers` import; `chown` outputs back to the host UID afterwards instead.\n- **`-e \u003Cspec>` is required, not optional** — current images hard-require it and exit with `ValueError: The subtask vcn_aoi requires the following argument: -e\u002F--experiment_spec_file` before parsing CLI overrides.\n\nSee `references\u002Fcontainer-setup.md` for the full path-mounting pattern, the `--user`\u002F`chown` rationale and `alpine` chown command, multi-`-v` guidance, and the `-e \u003Cspec>` requirement detail.\n\n---\n\n## Method\n\nThe whole skill is a single `docker run` invocation followed by a small visual spot-check. The container does Steps 1–4 internally (threshold sweep, weakness scoring, top-K selection, per-lighting expansion). You handle Step 5 (visual spot-check) directly with the Read tool.\n\n### Step 1–4 — Run the container\n\n```bash\n$DOCKER gap_analysis vcn_aoi \\\n    inference_results_dir=\u003Cexp_dir>\u002Finference\u002F\u003Clabel>\u002F \\\n    train_config=\u003Cexp_dir>\u002Ftrain.yaml \\\n    kpi_media_path=\u003Cdataset_root> \\\n    results_dir=\u003Crca_results_dir> \\\n    top_k_per_label=50\n```\n\n> **Always pass `top_k_per_label`.** This is the argument that switches the container\n> from the default \"samples below threshold\" filter into proper top-K-per-label\n> ranking. At `min_recall=1.0` the threshold is by construction at-or-below every\n> NO_PASS score, so the below-threshold filter returns ONLY misclassified PASS rows\n> and zero NO_PASS rows — useless as an augmentation queue. With `top_k_per_label`\n> set to a positive integer (either in the spec or as a Hydra override), the\n> container computes signed weakness against the threshold for every row and\n> surfaces the K weakest **per ground-truth label**, which is the per-label ranked\n> output downstream steps consume.\n\nReads `inference.csv`, sweeps every unique `siamese_score` plus one value just below the minimum, keeps the candidates with NO_PASS-class recall ≥ `min_recall` (with `1e-12` tolerance), then picks the threshold with the best F1 (tie-break: precision, then threshold value). For every row, computes signed weakness from that threshold (positive = misclassified, negative = correct, magnitude = margin). Sorts by weakness descending and takes the top `top_k_per_label` per ground-truth label, then expands each weak row into one row per lighting condition using `dataset.classify.input_map` and `dataset.classify.image_ext` from the train YAML.\n\nIf **no** candidate threshold meets the recall target, the container exits non-zero and writes `unreachable_kpi.txt` into `results_dir` explaining which recall the model can actually achieve. In that case, stop the analysis after the docker call, write a one-section report explaining the model fundamentally cannot reach the KPI at any operating point, and recommend retraining or relabeling — skip the visual spot-check.\n\n**Container writes into `results_dir`:**\n\n| Artifact | Contents |\n|----------|----------|\n| `kpi_gaps.parquet` | Top-K weakest per label, expanded per lighting. Columns: `filepath`, `label`, `siamese_score`, `weakness`. |\n| `threshold.txt` | Chosen decision threshold (single float, plain text). |\n| `metrics.json` | At the chosen threshold: `precision`, `recall`, `f1`, confusion matrix `{tp, fp, tn, fn}`, plus per-label `{total, mean_weakness, median_weakness, max_weakness, n_misclassified}`. |\n| `weak_samples_breakdown.txt` | Per-label kept-row breakdown: `\u003Ccount>` total, `\u003C%>` of all kept rows, `N` misclassified (weakness > 0), `N` marginal (weakness ≤ 0). |\n| `unreachable_kpi.txt` | Only written when the recall target is unreachable. Presence of this file means: skip Step 5, write the abridged report, recommend retrain. |\n\nPrint the container's stdout summary (chosen threshold, kept-row counts, per-label breakdown) to your own stdout so the script-check hook can verify the run produced output.\n\n### Step 5 — Visual spot check (small, fixed)\n\nSkip this step if `unreachable_kpi.txt` exists. Otherwise use the Read tool to **view** the 5 weakest PASS samples and the 5 weakest NO_PASS samples from `kpi_gaps.parquet` (deduplicated to one row per sample, using the FIRST-lighting `filepath`), classify each as exactly one of **mislabeled** \u002F **edge case** \u002F **data quality** \u002F **systematic**, and copy each viewed image (resized to 128×128 if PIL is available, otherwise just copy) into `\u003Cresults_dir>\u002Frca_images\u002F`. This is the only image inspection required — do not view dozens of images, run failure mode clustering, or audit goldens (VCN has no golden images).\n\nSee `references\u002Fvisual-spot-check.md` for the exact sample-selection sort, the per-lighting deduplication rule, the full definition of each verdict category, and the image-copy detail.\n\n---\n\n## Reference invocation\n\nPaste-and-edit the workspace, the four paths, and the two numeric knobs; this runs end-to-end. Capture stdout so the script-check hook sees row counts.\n\n```bash\nWORKSPACE=\u003Cabsolute path>            # mounted identically inside the container\nEXP_DIR=\u003Cexperiment_result_dir>      # contains inference\u002Finference.csv and train.yaml; must be inside $WORKSPACE\nDATASET_ROOT=\u003Cdataset_root>          # image root for inference.csv input_path entries; must be inside $WORKSPACE\nMIN_RECALL=1.0                       # zero-miss default; lower if KPI relaxes\nTOP_K=50                             # per-label augmentation budget\nOUT=\"$EXP_DIR\u002Frca_results\u002F$(date +%Y-%m-%d_%H%M%S)\"\nSPEC=\"$OUT\u002Fvcn_aoi_spec.yaml\"\nIMG=$(python3 -c \"import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'\u002Fversions.yaml'))['images']['tao_toolkit']['data_services'])\")\n\nmkdir -p \"$OUT\"\n\n# Write the gap-analysis spec for this run\ncat > \"$SPEC\" \u003C\u003CEOF\nmin_recall: $MIN_RECALL\ntop_k_per_label: $TOP_K\nEOF\n\ndocker run --gpus all --rm --ipc=host \\\n    -v \"$WORKSPACE:$WORKSPACE\" -w \"$WORKSPACE\" \\\n    \"$IMG\" gap_analysis vcn_aoi \\\n    -e \"$SPEC\" \\\n    inference_results_dir=\"$EXP_DIR\u002Finference\u002Flatest\u002F\" \\\n    train_config=\"$EXP_DIR\u002Ftrain.yaml\" \\\n    kpi_media_path=\"$DATASET_ROOT\" \\\n    results_dir=\"$OUT\"\n\n# Container writes as root with --user dropped; chown back to host UID if needed.\ndocker run --rm -v \"$WORKSPACE:\u002Fw\" alpine chown -R \"$(id -u):$(id -g)\" \"\u002Fw\u002F$(realpath --relative-to=\"$WORKSPACE\" \"$OUT\")\"\n\n# Sanity print so the script-check hook sees real numbers\npython3 - \"$OUT\" \u003C\u003C 'PYEOF'\nimport json, os, sys\nout = sys.argv[1]\nunreachable = os.path.join(out, \"unreachable_kpi.txt\")\nif os.path.isfile(unreachable):\n    print(\"KPI UNREACHABLE — see\", unreachable)\n    sys.exit(0)\nwith open(os.path.join(out, \"threshold.txt\")) as f:\n    print(\"threshold:\", f.read().strip())\nwith open(os.path.join(out, \"metrics.json\")) as f:\n    m = json.load(f)\nprint(f\"precision={m['precision']:.4f} recall={m['recall']:.4f} f1={m['f1']:.4f}\")\nimport pandas as pd\ndf = pd.read_parquet(os.path.join(out, \"kpi_gaps.parquet\"))\nprint(f\"kpi_gaps.parquet: rows={len(df)}, cols={list(df.columns)}\")\nprint(df['label'].value_counts())\nPYEOF\n```\n\n---\n\n## Outputs\n\nWrite everything into a timestamped folder under the experiment result directory. The container's outputs go straight there; the visual spot-check writes `rca_images\u002F`; any runtime packaging hook may add session\u002Fconfig capture artifacts after `RCA_Report.md` is written.\n\n```\n\u003Cexperiment_result_dir>\u002Frca_results\u002FYYYY-MM-DD_HHMMSS\u002F\n├── RCA_Report.md              # Full gap analysis report (you write this)\n├── kpi_gaps.parquet           # Container: top-K weakest per label, expanded per lighting\n├── threshold.txt              # Container: chosen decision threshold (single float)\n├── metrics.json               # Container: confusion matrix + per-label distribution stats\n├── weak_samples_breakdown.txt # Container: per-label count\u002Fmisclassified\u002Fmarginal counts\n├── unreachable_kpi.txt        # Container: ONLY when no threshold meets min_recall\n├── rca_images\u002F                # You: thumbnails of the 10 viewed weak samples\n├── rca_config\u002F                # Auto-copied by hook\n└── session log\u002Fartifacts      # Optional, runtime-dependent packaging capture\n```\n\nAt the start of the run, get the real timestamp by running `date +%Y-%m-%d_%H%M%S` in Bash. Do NOT hardcode or guess. If the user specifies a custom output path, use that instead but maintain the same internal structure.\n\n---\n\n## Common pitfalls\n\nThe single most consequential failure mode is **forgetting `top_k_per_label` when `min_recall=1.0`**: at that recall the chosen threshold sits at or below every NO_PASS score, so without `top_k_per_label` the container falls back to a \"samples below threshold\" filter that returns ONLY misclassified PASS rows and zero NO_PASS rows, breaking the augmentation queue. Always include an explicit positive `top_k_per_label` (default 50) in the spec or as a Hydra override.\n\nSee `references\u002Fpitfalls.md` for the complete checklist, covering: forgetting `top_k_per_label`; passing `--user`; calling with only Hydra overrides (no `-e \u003Cspec>`); spec file outside `$WORKSPACE`; spec file with unresolved `???` sentinels; image not pulled \u002F wrong tag; path-mount mismatch; `unreachable_kpi.txt` written; `inference.csv` missing required columns; train YAML missing `dataset.classify.input_map` or `image_ext`; `kpi_media_path` not matching `input_path` prefixes; and no GPU detected from inside the container.\n\n---\n\n## Report Structure\n\nWrite `RCA_Report.md` as a tight (1000–1800 word) computational gap analysis — depth comes from accurate numbers and a clear action list, not narrative. The full report template (7 sections: Verdict, Threshold Selection, Weakness Distribution, Top-K Weakest Samples, Visual Spot Check, Per-Label Breakdown, Recommended Actions — with the confusion-matrix and table layouts) is in `references\u002Foutput-template.md`. When `unreachable_kpi.txt` exists, replace sections 3–6 with a single short section quoting that file's contents and collapse section 7 to one recommendation: retrain or relabel.\n\n---\n\n## Execution Order\n\n1. Resolve `DS_IMAGE` from `versions.yaml` (`images.tao_toolkit.data_services`), then run `docker info`, `nvidia-smi`, and `docker image inspect \"$DS_IMAGE\"` (pulling if missing) once to confirm the environment. Abort with a clear message if any fail.\n2. Run `date +%Y-%m-%d_%H%M%S` to get the timestamp; create `\u003Cexperiment_result_dir>\u002Frca_results\u002F\u003Ctimestamp>\u002F`.\n3. Write `vcn_aoi_spec.yaml` into the timestamped dir with `min_recall` and `top_k_per_label` filled in. Keep it under `$WORKSPACE` so the `-e` path resolves inside the container.\n4. Run `docker run … \"$DS_IMAGE\" gap_analysis vcn_aoi -e vcn_aoi_spec.yaml inference_results_dir=… train_config=… kpi_media_path=… output_dir=…`. The container writes `kpi_gaps.parquet`, `threshold.txt`, `metrics.json`, `weak_samples_breakdown.txt` into `results_dir`. Print the chosen threshold and kept-row counts to stdout so the script-check hook can verify the run produced output.\n5. If `unreachable_kpi.txt` exists, skip Step 6 and write the abridged report. Otherwise continue.\n6. Pick 10 weak samples (5 weakest PASS + 5 weakest NO_PASS) from `kpi_gaps.parquet`, view each test image with Read, classify, and copy each into `rca_images\u002F`.\n7. Write `RCA_Report.md` last — writing it triggers the packaging hook, which copies session logs and skill config alongside.\n",{"name":5,"tags":49,"license":15,"metadata":54,"description":7,"allowed-tools":57,"compatibility":58},[50,51,52,53],"data","rca","vcn","aoi",{"author":55,"version":56},"NVIDIA Corporation","0.1.0","Read Bash","Requires docker + nvidia-container-toolkit and a CUDA GPU. Pulls the `tao_toolkit.data_services` image declared in `versions.yaml` at the skill bank root.","claude\u002Finstall-gsd-build-foQdV","d86cd127f527124b5fd0fd0bc679a4d79b7d01d7",".agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet","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":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add pattanation\u002FNorvik --skill tao-analyze-gaps-visual-changenet",{"tool":72,"command":73},"bunx","bunx skills add pattanation\u002FNorvik --skill tao-analyze-gaps-visual-changenet",{"tool":75,"command":76},"pnpm","pnpm dlx skills add pattanation\u002FNorvik --skill tao-analyze-gaps-visual-changenet","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002FSKILL.md",true,[80,86,90,96,100,104,108,112,116,120,124,128,132,136],{"path":81,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":84,"sourceHtmlUrl":85},"BENCHMARK.md","REFERENCE","参考文档",4151,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002FBENCHMARK.md",{"path":87,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":88,"sourceHtmlUrl":89},"evals\u002Fevals.json",844,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fevals\u002Fevals.json",{"path":91,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":94,"sourceHtmlUrl":95},"hooks\u002F_parse-stdin.sh","SCRIPT","脚本",1471,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002F_parse-stdin.sh",{"path":97,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":98,"sourceHtmlUrl":99},"hooks\u002Frca-artifacts-check.sh",5018,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002Frca-artifacts-check.sh",{"path":101,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":102,"sourceHtmlUrl":103},"hooks\u002Frca-label-coverage.sh",3490,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002Frca-label-coverage.sh",{"path":105,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":106,"sourceHtmlUrl":107},"hooks\u002Frca-package.sh",2964,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002Frca-package.sh",{"path":109,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":110,"sourceHtmlUrl":111},"hooks\u002Frca-script-check.sh",5787,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002Frca-script-check.sh",{"path":113,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":114,"sourceHtmlUrl":115},"hooks\u002Frca-section-check.sh",3334,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fhooks\u002Frca-section-check.sh",{"path":117,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":118,"sourceHtmlUrl":119},"references\u002Fcontainer-setup.md",3084,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Freferences\u002Fcontainer-setup.md",{"path":121,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":122,"sourceHtmlUrl":123},"references\u002Foutput-template.md",3308,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Freferences\u002Foutput-template.md",{"path":125,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":126,"sourceHtmlUrl":127},"references\u002Fpitfalls.md",3943,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Freferences\u002Fpitfalls.md",{"path":129,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":130,"sourceHtmlUrl":131},"references\u002Fvisual-spot-check.md",1602,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Freferences\u002Fvisual-spot-check.md",{"path":133,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":134,"sourceHtmlUrl":135},"skill-card.md",4046,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fskill-card.md",{"path":137,"resourceType":138,"resourceTypeDesc":139,"sizeBytes":140,"sourceHtmlUrl":141},"skill.oms.sig","OTHER","其他",6997,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Ftao-analyze-gaps-visual-changenet\u002Fskill.oms.sig",[143,174,200,224,245,260],{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":156,"publishedAt":44},"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",[150,153],{"categoryNo":151,"categoryName":152,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173],"webapp","testing","webapp testing","for","applications","local","frontend","debugging","toolkit","logs","browser","with","playwright","web","behavior","ui","screenshots",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":178,"sourceHtmlUrl":179,"categories":180,"keywords":182,"publishedAt":44},"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",[181],{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},[183,184,185,170,186,187,188,160,189,190,163,191,192,193,194,195,196,197,198,199],"builder","artifacts builder","artifacts","web artifacts builder","single-file","css","Tailwind","ui components","single","use","file","components","react","multi","state","routing","state management",{"skillNo":201,"name":202,"nameZh":6,"description":203,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":204,"licenseFileUrl":205,"sourceHtmlUrl":206,"categories":207,"keywords":209,"publishedAt":44},"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",[208],{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},[210,211,212,213,214,215,216,217,218,219,220,221,222,223],"functions","vueuse","vueuse functions","project","nuxt","apply","github","concise","build","https","features","vue","js","composables",{"skillNo":225,"name":226,"nameZh":6,"description":227,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":204,"licenseFileUrl":228,"sourceHtmlUrl":229,"categories":230,"keywords":233,"publishedAt":44},"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",[231,232],{"categoryNo":151,"categoryName":152,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},[234,158,235,221,236,169,237,238,36,216,239,160,240,241,242,192,243,222,244],"vue testing best practices","testing best practices","best practices","test","testing patterns","vitest","mocking","e2e","utils","patterns","e2e testing",{"skillNo":246,"name":247,"nameZh":6,"description":248,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":204,"licenseFileUrl":249,"sourceHtmlUrl":250,"categories":251,"keywords":253,"publishedAt":44},"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",[252],{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},[254,221,255,236,256,36,257,216,243,258,259],"router","vue router best practices","route","guards","navigation","lifecycle",{"skillNo":261,"name":262,"nameZh":6,"description":263,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":204,"licenseFileUrl":264,"sourceHtmlUrl":265,"categories":266,"keywords":268,"publishedAt":44},"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",[267],{"categoryNo":154,"categoryName":155,"taxonomyType":21,"taxonomyTypeDesc":22},[269,221,236,270,213,271,272,273,254,274,275,276,277,278,279,160,280,192,281,282],"vue best practices","Composition","files","tasks","api","pinia","work","options","ssr","typescript","as","vite","load","standard"]