[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-nvidia-tao-analyze-gaps-visual-changenet":3,"mdc-bjim7h-key":34,"related-repo-nvidia-tao-analyze-gaps-visual-changenet":2963,"related-org-nvidia-tao-analyze-gaps-visual-changenet":3065},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"tao-analyze-gaps-visual-changenet","perform gap analysis on NVIDIA TAO experiments","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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"nvidia","NVIDIA","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fnvidia.png",[12,16,17,20],{"name":13,"slug":14,"type":15},"Data Analysis","data-analysis","tag",{"name":9,"slug":8,"type":15},{"name":18,"slug":19,"type":15},"Docker","docker",{"name":21,"slug":22,"type":15},"Computer Vision","computer-vision",2473,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002Fskills","2026-07-14T05:27:56.871252","Apache-2.0",281,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"AI agent skills published by NVIDIA","https:\u002F\u002Fgithub.com\u002FNVIDIA\u002Fskills\u002Ftree\u002FHEAD\u002Fskills\u002Ftao-analyze-gaps-visual-changenet","---\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",{"data":35,"body":46},{"name":4,"description":6,"license":26,"compatibility":36,"metadata":37,"allowed-tools":40,"tags":41},"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.",{"author":38,"version":39},"NVIDIA Corporation","0.1.0","Read Bash",[42,43,44,45],"data","rca","vcn","aoi",{"type":47,"children":48},"root",[49,58,80,173,233,237,244,442,445,451,469,737,748,753,847,898,901,907,919,926,1098,1139,1194,1221,1236,1441,1446,1452,1519,1531,1534,1540,1545,2527,2530,2536,2557,2567,2580,2583,2589,2627,2718,2721,2727,2754,2757,2763,2957],{"type":50,"tag":51,"props":52,"children":54},"element","h1",{"id":53},"tao-vcn-classify-gap-analysis-skill",[55],{"type":56,"value":57},"text","TAO VCN Classify Gap Analysis Skill",{"type":50,"tag":59,"props":60,"children":61},"p",{},[62,64,70,72,78],{"type":56,"value":63},"You are an analyst for NVIDIA TAO VCN Classify (Visual Component Net) inference results. Your job is to identify the ",{"type":50,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":56,"value":69},"weakest samples per ground-truth label",{"type":56,"value":71}," by measuring signed distance from the decision threshold ",{"type":50,"tag":73,"props":74,"children":75},"em",{},[76],{"type":56,"value":77},"in the wrong direction",{"type":56,"value":79},", then surface them for downstream augmentation or relabeling.",{"type":50,"tag":59,"props":81,"children":82},{},[83,85,92,94,100,102,108,110,116,118,124,126,132,134,140,142,148,150,156,158,164,166,171],{"type":56,"value":84},"This skill is intentionally lightweight. VCN's classify head is a single-score binary boundary (PASS vs NO_PASS by ",{"type":50,"tag":86,"props":87,"children":89},"code",{"className":88},[],[90],{"type":56,"value":91},"siamese_score",{"type":56,"value":93},"), so the analysis is computational, not investigative. The whole computation lives behind one direct ",{"type":50,"tag":86,"props":95,"children":97},{"className":96},[],[98],{"type":56,"value":99},"docker run",{"type":56,"value":101}," invocation against the ",{"type":50,"tag":86,"props":103,"children":105},{"className":104},[],[106],{"type":56,"value":107},"tao_toolkit.data_services",{"type":56,"value":109}," image declared in ",{"type":50,"tag":86,"props":111,"children":113},{"className":112},[],[114],{"type":56,"value":115},"versions.yaml",{"type":56,"value":117}," (resolved at runtime — see Setup). The container's entrypoint takes ",{"type":50,"tag":86,"props":119,"children":121},{"className":120},[],[122],{"type":56,"value":123},"\u003Ccategory> \u003Caction> [hydra overrides...]",{"type":56,"value":125},"; we pass ",{"type":50,"tag":86,"props":127,"children":129},{"className":128},[],[130],{"type":56,"value":131},"gap_analysis vcn_aoi key=value …",{"type":56,"value":133},". Each override is a bare Hydra ",{"type":50,"tag":86,"props":135,"children":137},{"className":136},[],[138],{"type":56,"value":139},"key=value",{"type":56,"value":141}," that selectively overrides the script's ",{"type":50,"tag":86,"props":143,"children":145},{"className":144},[],[146],{"type":56,"value":147},"GapAnalysisConfig",{"type":56,"value":149}," schema (defaults are baked into the container; introspect with ",{"type":50,"tag":86,"props":151,"children":153},{"className":152},[],[154],{"type":56,"value":155},"docker run ... gap_analysis vcn_aoi --cfg=job",{"type":56,"value":157},"). (There is no ",{"type":50,"tag":86,"props":159,"children":161},{"className":160},[],[162],{"type":56,"value":163},"dataset",{"type":56,"value":165}," keyword inside the container — that's the TAO launcher's pillar prefix and is dropped here.) You do ",{"type":50,"tag":65,"props":167,"children":168},{},[169],{"type":56,"value":170},"not",{"type":56,"value":172}," 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.",{"type":50,"tag":59,"props":174,"children":175},{},[176,178,184,186,192,194,200,202,208,210,216,217,223,225,231],{"type":56,"value":177},"CLI surface can shift between data-services container builds. If a ",{"type":50,"tag":86,"props":179,"children":181},{"className":180},[],[182],{"type":56,"value":183},"gap_analysis vcn_aoi",{"type":56,"value":185}," invocation fails on argument parsing, introspect the actual schema once per image with ",{"type":50,"tag":86,"props":187,"children":189},{"className":188},[],[190],{"type":56,"value":191},"docker run --rm \"$DS_IMAGE\" gap_analysis vcn_aoi --cfg=job",{"type":56,"value":193}," and reconcile any renamed keys (e.g. ",{"type":50,"tag":86,"props":195,"children":197},{"className":196},[],[198],{"type":56,"value":199},"inference_csv",{"type":56,"value":201}," vs ",{"type":50,"tag":86,"props":203,"children":205},{"className":204},[],[206],{"type":56,"value":207},"inference_results_dir",{"type":56,"value":209},", ",{"type":50,"tag":86,"props":211,"children":213},{"className":212},[],[214],{"type":56,"value":215},"output_dir",{"type":56,"value":201},{"type":50,"tag":86,"props":218,"children":220},{"className":219},[],[221],{"type":56,"value":222},"results_dir",{"type":56,"value":224},") before retrying. Output parquet name is ",{"type":50,"tag":86,"props":226,"children":228},{"className":227},[],[229],{"type":56,"value":230},"kpi_gaps.parquet",{"type":56,"value":232},".",{"type":50,"tag":234,"props":235,"children":236},"hr",{},[],{"type":50,"tag":238,"props":239,"children":241},"h2",{"id":240},"inputs",[242],{"type":56,"value":243},"Inputs",{"type":50,"tag":245,"props":246,"children":247},"ol",{},[248,317,343,368],{"type":50,"tag":249,"props":250,"children":251},"li",{},[252,257,259,265,267,273,274,280,281,287,288,293,295,300,302,308,310,316],{"type":50,"tag":65,"props":253,"children":254},{},[255],{"type":56,"value":256},"Experiment result directory",{"type":56,"value":258}," — contains ",{"type":50,"tag":86,"props":260,"children":262},{"className":261},[],[263],{"type":56,"value":264},"inference\u002Finference.csv",{"type":56,"value":266}," from TAO VCN Classify inference. Required columns: ",{"type":50,"tag":86,"props":268,"children":270},{"className":269},[],[271],{"type":56,"value":272},"input_path",{"type":56,"value":209},{"type":50,"tag":86,"props":275,"children":277},{"className":276},[],[278],{"type":56,"value":279},"object_name",{"type":56,"value":209},{"type":50,"tag":86,"props":282,"children":284},{"className":283},[],[285],{"type":56,"value":286},"label",{"type":56,"value":209},{"type":50,"tag":86,"props":289,"children":291},{"className":290},[],[292],{"type":56,"value":91},{"type":56,"value":294},". Pass the ",{"type":50,"tag":65,"props":296,"children":297},{},[298],{"type":56,"value":299},"directory",{"type":56,"value":301}," (e.g. ",{"type":50,"tag":86,"props":303,"children":305},{"className":304},[],[306],{"type":56,"value":307},"inference\u002Flatest\u002F",{"type":56,"value":309},"), not the CSV file — the container reads ",{"type":50,"tag":86,"props":311,"children":313},{"className":312},[],[314],{"type":56,"value":315},"inference_results_dir\u002Finference.csv",{"type":56,"value":232},{"type":50,"tag":249,"props":318,"children":319},{},[320,325,327,333,335,341],{"type":50,"tag":65,"props":321,"children":322},{},[323],{"type":56,"value":324},"Training code\u002Fconfig directory",{"type":56,"value":326}," — contains the VCN train YAML. The container reads ",{"type":50,"tag":86,"props":328,"children":330},{"className":329},[],[331],{"type":56,"value":332},"dataset.classify.input_map",{"type":56,"value":334}," (lighting condition list) and ",{"type":50,"tag":86,"props":336,"children":338},{"className":337},[],[339],{"type":56,"value":340},"dataset.classify.image_ext",{"type":56,"value":342}," from it to expand each weak sample into one row per lighting.",{"type":50,"tag":249,"props":344,"children":345},{},[346,351,353,358,360,366],{"type":50,"tag":65,"props":347,"children":348},{},[349],{"type":56,"value":350},"Dataset directory",{"type":56,"value":352}," — image root prepended to the relative ",{"type":50,"tag":86,"props":354,"children":356},{"className":355},[],[357],{"type":56,"value":272},{"type":56,"value":359}," from each row (",{"type":50,"tag":86,"props":361,"children":363},{"className":362},[],[364],{"type":56,"value":365},"kpi_media_path",{"type":56,"value":367},").",{"type":50,"tag":249,"props":369,"children":370},{},[371,376,378,384,385,391,393,399,401,407,408,414,415,421,423,433,435,440],{"type":50,"tag":65,"props":372,"children":373},{},[374],{"type":56,"value":375},"Schema overrides",{"type":56,"value":377}," — ",{"type":50,"tag":86,"props":379,"children":381},{"className":380},[],[382],{"type":56,"value":383},"min_recall",{"type":56,"value":209},{"type":50,"tag":86,"props":386,"children":388},{"className":387},[],[389],{"type":56,"value":390},"top_k_per_label",{"type":56,"value":392},", and optionally a hard-pinned ",{"type":50,"tag":86,"props":394,"children":396},{"className":395},[],[397],{"type":56,"value":398},"threshold",{"type":56,"value":400}," are passed as Hydra overrides (defaults: ",{"type":50,"tag":86,"props":402,"children":404},{"className":403},[],[405],{"type":56,"value":406},"min_recall=1.0",{"type":56,"value":209},{"type":50,"tag":86,"props":409,"children":411},{"className":410},[],[412],{"type":56,"value":413},"top_k_per_label=50",{"type":56,"value":209},{"type":50,"tag":86,"props":416,"children":418},{"className":417},[],[419],{"type":56,"value":420},"threshold=-1.0",{"type":56,"value":422}," meaning sweep). ",{"type":50,"tag":65,"props":424,"children":425},{},[426,431],{"type":50,"tag":86,"props":427,"children":429},{"className":428},[],[430],{"type":56,"value":390},{"type":56,"value":432}," must be a positive integer",{"type":56,"value":434}," — omitting it flips the container into \"below-threshold filter\" mode, which at ",{"type":50,"tag":86,"props":436,"children":438},{"className":437},[],[439],{"type":56,"value":406},{"type":56,"value":441}," returns only PASS misclassifications and zero NO_PASS rows. See Common pitfalls.",{"type":50,"tag":234,"props":443,"children":444},{},[],{"type":50,"tag":238,"props":446,"children":448},{"id":447},"setup",[449],{"type":56,"value":450},"Setup",{"type":50,"tag":59,"props":452,"children":453},{},[454,456,461,462,467],{"type":56,"value":455},"The threshold sweep, weakness ranking, and per-lighting expansion all run inside the ",{"type":50,"tag":86,"props":457,"children":459},{"className":458},[],[460],{"type":56,"value":107},{"type":56,"value":109},{"type":50,"tag":86,"props":463,"children":465},{"className":464},[],[466],{"type":56,"value":115},{"type":56,"value":468},". 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:",{"type":50,"tag":470,"props":471,"children":476},"pre",{"className":472,"code":473,"language":474,"meta":475,"style":475},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# 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","bash","",[477],{"type":50,"tag":86,"props":478,"children":479},{"__ignoreMap":475},[480,492,540,569,579,625,663,706],{"type":50,"tag":481,"props":482,"children":485},"span",{"class":483,"line":484},"line",1,[486],{"type":50,"tag":481,"props":487,"children":489},{"style":488},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[490],{"type":56,"value":491},"# Resolve tao_toolkit.data_services → concrete nvcr.io\u002F... URI from versions.yaml\n",{"type":50,"tag":481,"props":493,"children":495},{"class":483,"line":494},2,[496,502,508,514,520,525,530,535],{"type":50,"tag":481,"props":497,"children":499},{"style":498},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[500],{"type":56,"value":501},"DS_IMAGE",{"type":50,"tag":481,"props":503,"children":505},{"style":504},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[506],{"type":56,"value":507},"=$(",{"type":50,"tag":481,"props":509,"children":511},{"style":510},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[512],{"type":56,"value":513},"python3",{"type":50,"tag":481,"props":515,"children":517},{"style":516},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[518],{"type":56,"value":519}," -c",{"type":50,"tag":481,"props":521,"children":522},{"style":504},[523],{"type":56,"value":524}," \"",{"type":50,"tag":481,"props":526,"children":527},{"style":516},[528],{"type":56,"value":529},"import yaml,os; print(yaml.safe_load(open(os.environ['TAO_SKILL_BANK_PATH']+'\u002Fversions.yaml'))['images']['tao_toolkit']['data_services'])",{"type":50,"tag":481,"props":531,"children":532},{"style":504},[533],{"type":56,"value":534},"\"",{"type":50,"tag":481,"props":536,"children":537},{"style":504},[538],{"type":56,"value":539},")\n",{"type":50,"tag":481,"props":541,"children":543},{"class":483,"line":542},3,[544,550,554,559,564],{"type":50,"tag":481,"props":545,"children":547},{"style":546},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[548],{"type":56,"value":549},"echo",{"type":50,"tag":481,"props":551,"children":552},{"style":504},[553],{"type":56,"value":524},{"type":50,"tag":481,"props":555,"children":556},{"style":516},[557],{"type":56,"value":558},"DS_IMAGE=",{"type":50,"tag":481,"props":560,"children":561},{"style":498},[562],{"type":56,"value":563},"$DS_IMAGE",{"type":50,"tag":481,"props":565,"children":566},{"style":504},[567],{"type":56,"value":568},"\"\n",{"type":50,"tag":481,"props":570,"children":572},{"class":483,"line":571},4,[573],{"type":50,"tag":481,"props":574,"children":576},{"emptyLinePlaceholder":575},true,[577],{"type":56,"value":578},"\n",{"type":50,"tag":481,"props":580,"children":582},{"class":483,"line":581},5,[583,587,592,597,602,607,612,616,621],{"type":50,"tag":481,"props":584,"children":585},{"style":510},[586],{"type":56,"value":19},{"type":50,"tag":481,"props":588,"children":589},{"style":516},[590],{"type":56,"value":591}," info",{"type":50,"tag":481,"props":593,"children":594},{"style":504},[595],{"type":56,"value":596}," >",{"type":50,"tag":481,"props":598,"children":599},{"style":516},[600],{"type":56,"value":601}," \u002Fdev\u002Fnull",{"type":50,"tag":481,"props":603,"children":604},{"style":504},[605],{"type":56,"value":606}," &&",{"type":50,"tag":481,"props":608,"children":609},{"style":546},[610],{"type":56,"value":611}," echo",{"type":50,"tag":481,"props":613,"children":614},{"style":504},[615],{"type":56,"value":524},{"type":50,"tag":481,"props":617,"children":618},{"style":516},[619],{"type":56,"value":620},"OK: docker",{"type":50,"tag":481,"props":622,"children":623},{"style":504},[624],{"type":56,"value":568},{"type":50,"tag":481,"props":626,"children":628},{"class":483,"line":627},6,[629,634,638,642,646,650,654,659],{"type":50,"tag":481,"props":630,"children":631},{"style":510},[632],{"type":56,"value":633},"nvidia-smi",{"type":50,"tag":481,"props":635,"children":636},{"style":504},[637],{"type":56,"value":596},{"type":50,"tag":481,"props":639,"children":640},{"style":516},[641],{"type":56,"value":601},{"type":50,"tag":481,"props":643,"children":644},{"style":504},[645],{"type":56,"value":606},{"type":50,"tag":481,"props":647,"children":648},{"style":546},[649],{"type":56,"value":611},{"type":50,"tag":481,"props":651,"children":652},{"style":504},[653],{"type":56,"value":524},{"type":50,"tag":481,"props":655,"children":656},{"style":516},[657],{"type":56,"value":658},"OK: GPU",{"type":50,"tag":481,"props":660,"children":661},{"style":504},[662],{"type":56,"value":568},{"type":50,"tag":481,"props":664,"children":666},{"class":483,"line":665},7,[667,671,676,681,685,689,693,697,701],{"type":50,"tag":481,"props":668,"children":669},{"style":510},[670],{"type":56,"value":19},{"type":50,"tag":481,"props":672,"children":673},{"style":516},[674],{"type":56,"value":675}," image",{"type":50,"tag":481,"props":677,"children":678},{"style":516},[679],{"type":56,"value":680}," inspect",{"type":50,"tag":481,"props":682,"children":683},{"style":504},[684],{"type":56,"value":524},{"type":50,"tag":481,"props":686,"children":687},{"style":498},[688],{"type":56,"value":563},{"type":50,"tag":481,"props":690,"children":691},{"style":504},[692],{"type":56,"value":534},{"type":50,"tag":481,"props":694,"children":695},{"style":504},[696],{"type":56,"value":596},{"type":50,"tag":481,"props":698,"children":699},{"style":516},[700],{"type":56,"value":601},{"type":50,"tag":481,"props":702,"children":703},{"style":498},[704],{"type":56,"value":705}," \\\n",{"type":50,"tag":481,"props":707,"children":709},{"class":483,"line":708},8,[710,715,720,725,729,733],{"type":50,"tag":481,"props":711,"children":712},{"style":504},[713],{"type":56,"value":714},"  ||",{"type":50,"tag":481,"props":716,"children":717},{"style":510},[718],{"type":56,"value":719}," docker",{"type":50,"tag":481,"props":721,"children":722},{"style":516},[723],{"type":56,"value":724}," pull",{"type":50,"tag":481,"props":726,"children":727},{"style":504},[728],{"type":56,"value":524},{"type":50,"tag":481,"props":730,"children":731},{"style":498},[732],{"type":56,"value":563},{"type":50,"tag":481,"props":734,"children":735},{"style":504},[736],{"type":56,"value":568},{"type":50,"tag":59,"props":738,"children":739},{},[740,746],{"type":50,"tag":86,"props":741,"children":743},{"className":742},[],[744],{"type":56,"value":745},"TAO_SKILL_BANK_PATH",{"type":56,"value":747}," 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.",{"type":50,"tag":59,"props":749,"children":750},{},[751],{"type":56,"value":752},"Three setup rules are load-bearing and easy to get wrong:",{"type":50,"tag":754,"props":755,"children":756},"ul",{},[757,783,823],{"type":50,"tag":249,"props":758,"children":759},{},[760,765,767,773,775,781],{"type":50,"tag":65,"props":761,"children":762},{},[763],{"type":56,"value":764},"Path mounting",{"type":56,"value":766}," — every host path the container reads or writes (",{"type":50,"tag":86,"props":768,"children":770},{"className":769},[],[771],{"type":56,"value":772},"inference.csv",{"type":56,"value":774},", train YAML, dataset image root, output dir) must be bind-mounted, simplest with ",{"type":50,"tag":86,"props":776,"children":778},{"className":777},[],[779],{"type":56,"value":780},"-v $WORKSPACE:$WORKSPACE -w $WORKSPACE",{"type":56,"value":782}," so absolute paths resolve identically on both sides.",{"type":50,"tag":249,"props":784,"children":785},{},[786,797,799,805,807,813,815,821],{"type":50,"tag":65,"props":787,"children":788},{},[789,791],{"type":56,"value":790},"Do not pass ",{"type":50,"tag":86,"props":792,"children":794},{"className":793},[],[795],{"type":56,"value":796},"--user $(id -u):$(id -g)",{"type":56,"value":798}," — it triggers ",{"type":50,"tag":86,"props":800,"children":802},{"className":801},[],[803],{"type":56,"value":804},"KeyError: 'getpwuid(): uid not found: \u003Cuid>'",{"type":56,"value":806}," during the container's ",{"type":50,"tag":86,"props":808,"children":810},{"className":809},[],[811],{"type":56,"value":812},"transformers",{"type":56,"value":814}," import; ",{"type":50,"tag":86,"props":816,"children":818},{"className":817},[],[819],{"type":56,"value":820},"chown",{"type":56,"value":822}," outputs back to the host UID afterwards instead.",{"type":50,"tag":249,"props":824,"children":825},{},[826,837,839,845],{"type":50,"tag":65,"props":827,"children":828},{},[829,835],{"type":50,"tag":86,"props":830,"children":832},{"className":831},[],[833],{"type":56,"value":834},"-e \u003Cspec>",{"type":56,"value":836}," is required, not optional",{"type":56,"value":838}," — current images hard-require it and exit with ",{"type":50,"tag":86,"props":840,"children":842},{"className":841},[],[843],{"type":56,"value":844},"ValueError: The subtask vcn_aoi requires the following argument: -e\u002F--experiment_spec_file",{"type":56,"value":846}," before parsing CLI overrides.",{"type":50,"tag":59,"props":848,"children":849},{},[850,852,858,860,866,868,873,875,881,883,889,891,896],{"type":56,"value":851},"See ",{"type":50,"tag":86,"props":853,"children":855},{"className":854},[],[856],{"type":56,"value":857},"references\u002Fcontainer-setup.md",{"type":56,"value":859}," for the full path-mounting pattern, the ",{"type":50,"tag":86,"props":861,"children":863},{"className":862},[],[864],{"type":56,"value":865},"--user",{"type":56,"value":867},"\u002F",{"type":50,"tag":86,"props":869,"children":871},{"className":870},[],[872],{"type":56,"value":820},{"type":56,"value":874}," rationale and ",{"type":50,"tag":86,"props":876,"children":878},{"className":877},[],[879],{"type":56,"value":880},"alpine",{"type":56,"value":882}," chown command, multi-",{"type":50,"tag":86,"props":884,"children":886},{"className":885},[],[887],{"type":56,"value":888},"-v",{"type":56,"value":890}," guidance, and the ",{"type":50,"tag":86,"props":892,"children":894},{"className":893},[],[895],{"type":56,"value":834},{"type":56,"value":897}," requirement detail.",{"type":50,"tag":234,"props":899,"children":900},{},[],{"type":50,"tag":238,"props":902,"children":904},{"id":903},"method",[905],{"type":56,"value":906},"Method",{"type":50,"tag":59,"props":908,"children":909},{},[910,912,917],{"type":56,"value":911},"The whole skill is a single ",{"type":50,"tag":86,"props":913,"children":915},{"className":914},[],[916],{"type":56,"value":99},{"type":56,"value":918}," 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.",{"type":50,"tag":920,"props":921,"children":923},"h3",{"id":922},"step-14-run-the-container",[924],{"type":56,"value":925},"Step 1–4 — Run the container",{"type":50,"tag":470,"props":927,"children":929},{"className":472,"code":928,"language":474,"meta":475,"style":475},"$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",[930],{"type":50,"tag":86,"props":931,"children":932},{"__ignoreMap":475},[933,941,990,1025,1055,1084],{"type":50,"tag":481,"props":934,"children":935},{"class":483,"line":484},[936],{"type":50,"tag":481,"props":937,"children":938},{"style":498},[939],{"type":56,"value":940},"$DOCKER gap_analysis vcn_aoi \\\n",{"type":50,"tag":481,"props":942,"children":943},{"class":483,"line":494},[944,949,954,959,964,969,974,978,982,986],{"type":50,"tag":481,"props":945,"children":946},{"style":498},[947],{"type":56,"value":948},"    inference_results_dir",{"type":50,"tag":481,"props":950,"children":951},{"style":504},[952],{"type":56,"value":953},"=\u003C",{"type":50,"tag":481,"props":955,"children":956},{"style":516},[957],{"type":56,"value":958},"exp_dir",{"type":50,"tag":481,"props":960,"children":961},{"style":504},[962],{"type":56,"value":963},">",{"type":50,"tag":481,"props":965,"children":966},{"style":516},[967],{"type":56,"value":968},"\u002Finference\u002F",{"type":50,"tag":481,"props":970,"children":971},{"style":504},[972],{"type":56,"value":973},"\u003C",{"type":50,"tag":481,"props":975,"children":976},{"style":516},[977],{"type":56,"value":286},{"type":50,"tag":481,"props":979,"children":980},{"style":504},[981],{"type":56,"value":963},{"type":50,"tag":481,"props":983,"children":984},{"style":516},[985],{"type":56,"value":867},{"type":50,"tag":481,"props":987,"children":988},{"style":510},[989],{"type":56,"value":705},{"type":50,"tag":481,"props":991,"children":992},{"class":483,"line":542},[993,998,1002,1007,1012,1016,1021],{"type":50,"tag":481,"props":994,"children":995},{"style":516},[996],{"type":56,"value":997},"    train_config=",{"type":50,"tag":481,"props":999,"children":1000},{"style":504},[1001],{"type":56,"value":973},{"type":50,"tag":481,"props":1003,"children":1004},{"style":516},[1005],{"type":56,"value":1006},"exp_di",{"type":50,"tag":481,"props":1008,"children":1009},{"style":498},[1010],{"type":56,"value":1011},"r",{"type":50,"tag":481,"props":1013,"children":1014},{"style":504},[1015],{"type":56,"value":963},{"type":50,"tag":481,"props":1017,"children":1018},{"style":516},[1019],{"type":56,"value":1020},"\u002Ftrain.yaml",{"type":50,"tag":481,"props":1022,"children":1023},{"style":498},[1024],{"type":56,"value":705},{"type":50,"tag":481,"props":1026,"children":1027},{"class":483,"line":571},[1028,1033,1037,1042,1047,1051],{"type":50,"tag":481,"props":1029,"children":1030},{"style":516},[1031],{"type":56,"value":1032},"    kpi_media_path=",{"type":50,"tag":481,"props":1034,"children":1035},{"style":504},[1036],{"type":56,"value":973},{"type":50,"tag":481,"props":1038,"children":1039},{"style":516},[1040],{"type":56,"value":1041},"dataset_roo",{"type":50,"tag":481,"props":1043,"children":1044},{"style":498},[1045],{"type":56,"value":1046},"t",{"type":50,"tag":481,"props":1048,"children":1049},{"style":504},[1050],{"type":56,"value":963},{"type":50,"tag":481,"props":1052,"children":1053},{"style":498},[1054],{"type":56,"value":705},{"type":50,"tag":481,"props":1056,"children":1057},{"class":483,"line":581},[1058,1063,1067,1072,1076,1080],{"type":50,"tag":481,"props":1059,"children":1060},{"style":516},[1061],{"type":56,"value":1062},"    results_dir=",{"type":50,"tag":481,"props":1064,"children":1065},{"style":504},[1066],{"type":56,"value":973},{"type":50,"tag":481,"props":1068,"children":1069},{"style":516},[1070],{"type":56,"value":1071},"rca_results_di",{"type":50,"tag":481,"props":1073,"children":1074},{"style":498},[1075],{"type":56,"value":1011},{"type":50,"tag":481,"props":1077,"children":1078},{"style":504},[1079],{"type":56,"value":963},{"type":50,"tag":481,"props":1081,"children":1082},{"style":498},[1083],{"type":56,"value":705},{"type":50,"tag":481,"props":1085,"children":1086},{"class":483,"line":627},[1087,1092],{"type":50,"tag":481,"props":1088,"children":1089},{"style":516},[1090],{"type":56,"value":1091},"    top_k_per_label=",{"type":50,"tag":481,"props":1093,"children":1095},{"style":1094},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1096],{"type":56,"value":1097},"50\n",{"type":50,"tag":1099,"props":1100,"children":1101},"blockquote",{},[1102],{"type":50,"tag":59,"props":1103,"children":1104},{},[1105,1116,1118,1123,1125,1130,1132,1137],{"type":50,"tag":65,"props":1106,"children":1107},{},[1108,1110,1115],{"type":56,"value":1109},"Always pass ",{"type":50,"tag":86,"props":1111,"children":1113},{"className":1112},[],[1114],{"type":56,"value":390},{"type":56,"value":232},{"type":56,"value":1117}," This is the argument that switches the container\nfrom the default \"samples below threshold\" filter into proper top-K-per-label\nranking. At ",{"type":50,"tag":86,"props":1119,"children":1121},{"className":1120},[],[1122],{"type":56,"value":406},{"type":56,"value":1124}," the threshold is by construction at-or-below every\nNO_PASS score, so the below-threshold filter returns ONLY misclassified PASS rows\nand zero NO_PASS rows — useless as an augmentation queue. With ",{"type":50,"tag":86,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":56,"value":390},{"type":56,"value":1131},"\nset to a positive integer (either in the spec or as a Hydra override), the\ncontainer computes signed weakness against the threshold for every row and\nsurfaces the K weakest ",{"type":50,"tag":65,"props":1133,"children":1134},{},[1135],{"type":56,"value":1136},"per ground-truth label",{"type":56,"value":1138},", which is the per-label ranked\noutput downstream steps consume.",{"type":50,"tag":59,"props":1140,"children":1141},{},[1142,1144,1149,1151,1156,1158,1163,1165,1171,1173,1178,1180,1185,1187,1192],{"type":56,"value":1143},"Reads ",{"type":50,"tag":86,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":56,"value":772},{"type":56,"value":1150},", sweeps every unique ",{"type":50,"tag":86,"props":1152,"children":1154},{"className":1153},[],[1155],{"type":56,"value":91},{"type":56,"value":1157}," plus one value just below the minimum, keeps the candidates with NO_PASS-class recall ≥ ",{"type":50,"tag":86,"props":1159,"children":1161},{"className":1160},[],[1162],{"type":56,"value":383},{"type":56,"value":1164}," (with ",{"type":50,"tag":86,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":56,"value":1170},"1e-12",{"type":56,"value":1172}," 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 ",{"type":50,"tag":86,"props":1174,"children":1176},{"className":1175},[],[1177],{"type":56,"value":390},{"type":56,"value":1179}," per ground-truth label, then expands each weak row into one row per lighting condition using ",{"type":50,"tag":86,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":56,"value":332},{"type":56,"value":1186}," and ",{"type":50,"tag":86,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":56,"value":340},{"type":56,"value":1193}," from the train YAML.",{"type":50,"tag":59,"props":1195,"children":1196},{},[1197,1199,1204,1206,1212,1214,1219],{"type":56,"value":1198},"If ",{"type":50,"tag":65,"props":1200,"children":1201},{},[1202],{"type":56,"value":1203},"no",{"type":56,"value":1205}," candidate threshold meets the recall target, the container exits non-zero and writes ",{"type":50,"tag":86,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":56,"value":1211},"unreachable_kpi.txt",{"type":56,"value":1213}," into ",{"type":50,"tag":86,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":56,"value":222},{"type":56,"value":1220}," 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.",{"type":50,"tag":59,"props":1222,"children":1223},{},[1224],{"type":50,"tag":65,"props":1225,"children":1226},{},[1227,1229,1234],{"type":56,"value":1228},"Container writes into ",{"type":50,"tag":86,"props":1230,"children":1232},{"className":1231},[],[1233],{"type":56,"value":222},{"type":56,"value":1235},":",{"type":50,"tag":1237,"props":1238,"children":1239},"table",{},[1240,1259],{"type":50,"tag":1241,"props":1242,"children":1243},"thead",{},[1244],{"type":50,"tag":1245,"props":1246,"children":1247},"tr",{},[1248,1254],{"type":50,"tag":1249,"props":1250,"children":1251},"th",{},[1252],{"type":56,"value":1253},"Artifact",{"type":50,"tag":1249,"props":1255,"children":1256},{},[1257],{"type":56,"value":1258},"Contents",{"type":50,"tag":1260,"props":1261,"children":1262},"tbody",{},[1263,1306,1323,1377,1425],{"type":50,"tag":1245,"props":1264,"children":1265},{},[1266,1275],{"type":50,"tag":1267,"props":1268,"children":1269},"td",{},[1270],{"type":50,"tag":86,"props":1271,"children":1273},{"className":1272},[],[1274],{"type":56,"value":230},{"type":50,"tag":1267,"props":1276,"children":1277},{},[1278,1280,1286,1287,1292,1293,1298,1299,1305],{"type":56,"value":1279},"Top-K weakest per label, expanded per lighting. Columns: ",{"type":50,"tag":86,"props":1281,"children":1283},{"className":1282},[],[1284],{"type":56,"value":1285},"filepath",{"type":56,"value":209},{"type":50,"tag":86,"props":1288,"children":1290},{"className":1289},[],[1291],{"type":56,"value":286},{"type":56,"value":209},{"type":50,"tag":86,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":56,"value":91},{"type":56,"value":209},{"type":50,"tag":86,"props":1300,"children":1302},{"className":1301},[],[1303],{"type":56,"value":1304},"weakness",{"type":56,"value":232},{"type":50,"tag":1245,"props":1307,"children":1308},{},[1309,1318],{"type":50,"tag":1267,"props":1310,"children":1311},{},[1312],{"type":50,"tag":86,"props":1313,"children":1315},{"className":1314},[],[1316],{"type":56,"value":1317},"threshold.txt",{"type":50,"tag":1267,"props":1319,"children":1320},{},[1321],{"type":56,"value":1322},"Chosen decision threshold (single float, plain text).",{"type":50,"tag":1245,"props":1324,"children":1325},{},[1326,1335],{"type":50,"tag":1267,"props":1327,"children":1328},{},[1329],{"type":50,"tag":86,"props":1330,"children":1332},{"className":1331},[],[1333],{"type":56,"value":1334},"metrics.json",{"type":50,"tag":1267,"props":1336,"children":1337},{},[1338,1340,1346,1347,1353,1354,1360,1362,1368,1370,1376],{"type":56,"value":1339},"At the chosen threshold: ",{"type":50,"tag":86,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":56,"value":1345},"precision",{"type":56,"value":209},{"type":50,"tag":86,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":56,"value":1352},"recall",{"type":56,"value":209},{"type":50,"tag":86,"props":1355,"children":1357},{"className":1356},[],[1358],{"type":56,"value":1359},"f1",{"type":56,"value":1361},", confusion matrix ",{"type":50,"tag":86,"props":1363,"children":1365},{"className":1364},[],[1366],{"type":56,"value":1367},"{tp, fp, tn, fn}",{"type":56,"value":1369},", plus per-label ",{"type":50,"tag":86,"props":1371,"children":1373},{"className":1372},[],[1374],{"type":56,"value":1375},"{total, mean_weakness, median_weakness, max_weakness, n_misclassified}",{"type":56,"value":232},{"type":50,"tag":1245,"props":1378,"children":1379},{},[1380,1389],{"type":50,"tag":1267,"props":1381,"children":1382},{},[1383],{"type":50,"tag":86,"props":1384,"children":1386},{"className":1385},[],[1387],{"type":56,"value":1388},"weak_samples_breakdown.txt",{"type":50,"tag":1267,"props":1390,"children":1391},{},[1392,1394,1400,1402,1408,1410,1416,1418,1423],{"type":56,"value":1393},"Per-label kept-row breakdown: ",{"type":50,"tag":86,"props":1395,"children":1397},{"className":1396},[],[1398],{"type":56,"value":1399},"\u003Ccount>",{"type":56,"value":1401}," total, ",{"type":50,"tag":86,"props":1403,"children":1405},{"className":1404},[],[1406],{"type":56,"value":1407},"\u003C%>",{"type":56,"value":1409}," of all kept rows, ",{"type":50,"tag":86,"props":1411,"children":1413},{"className":1412},[],[1414],{"type":56,"value":1415},"N",{"type":56,"value":1417}," misclassified (weakness > 0), ",{"type":50,"tag":86,"props":1419,"children":1421},{"className":1420},[],[1422],{"type":56,"value":1415},{"type":56,"value":1424}," marginal (weakness ≤ 0).",{"type":50,"tag":1245,"props":1426,"children":1427},{},[1428,1436],{"type":50,"tag":1267,"props":1429,"children":1430},{},[1431],{"type":50,"tag":86,"props":1432,"children":1434},{"className":1433},[],[1435],{"type":56,"value":1211},{"type":50,"tag":1267,"props":1437,"children":1438},{},[1439],{"type":56,"value":1440},"Only written when the recall target is unreachable. Presence of this file means: skip Step 5, write the abridged report, recommend retrain.",{"type":50,"tag":59,"props":1442,"children":1443},{},[1444],{"type":56,"value":1445},"Print 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.",{"type":50,"tag":920,"props":1447,"children":1449},{"id":1448},"step-5-visual-spot-check-small-fixed",[1450],{"type":56,"value":1451},"Step 5 — Visual spot check (small, fixed)",{"type":50,"tag":59,"props":1453,"children":1454},{},[1455,1457,1462,1464,1469,1471,1476,1478,1483,1485,1490,1492,1497,1498,1503,1504,1509,1511,1517],{"type":56,"value":1456},"Skip this step if ",{"type":50,"tag":86,"props":1458,"children":1460},{"className":1459},[],[1461],{"type":56,"value":1211},{"type":56,"value":1463}," exists. Otherwise use the Read tool to ",{"type":50,"tag":65,"props":1465,"children":1466},{},[1467],{"type":56,"value":1468},"view",{"type":56,"value":1470}," the 5 weakest PASS samples and the 5 weakest NO_PASS samples from ",{"type":50,"tag":86,"props":1472,"children":1474},{"className":1473},[],[1475],{"type":56,"value":230},{"type":56,"value":1477}," (deduplicated to one row per sample, using the FIRST-lighting ",{"type":50,"tag":86,"props":1479,"children":1481},{"className":1480},[],[1482],{"type":56,"value":1285},{"type":56,"value":1484},"), classify each as exactly one of ",{"type":50,"tag":65,"props":1486,"children":1487},{},[1488],{"type":56,"value":1489},"mislabeled",{"type":56,"value":1491}," \u002F ",{"type":50,"tag":65,"props":1493,"children":1494},{},[1495],{"type":56,"value":1496},"edge case",{"type":56,"value":1491},{"type":50,"tag":65,"props":1499,"children":1500},{},[1501],{"type":56,"value":1502},"data quality",{"type":56,"value":1491},{"type":50,"tag":65,"props":1505,"children":1506},{},[1507],{"type":56,"value":1508},"systematic",{"type":56,"value":1510},", and copy each viewed image (resized to 128×128 if PIL is available, otherwise just copy) into ",{"type":50,"tag":86,"props":1512,"children":1514},{"className":1513},[],[1515],{"type":56,"value":1516},"\u003Cresults_dir>\u002Frca_images\u002F",{"type":56,"value":1518},". 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).",{"type":50,"tag":59,"props":1520,"children":1521},{},[1522,1523,1529],{"type":56,"value":851},{"type":50,"tag":86,"props":1524,"children":1526},{"className":1525},[],[1527],{"type":56,"value":1528},"references\u002Fvisual-spot-check.md",{"type":56,"value":1530}," for the exact sample-selection sort, the per-lighting deduplication rule, the full definition of each verdict category, and the image-copy detail.",{"type":50,"tag":234,"props":1532,"children":1533},{},[],{"type":50,"tag":238,"props":1535,"children":1537},{"id":1536},"reference-invocation",[1538],{"type":56,"value":1539},"Reference invocation",{"type":50,"tag":59,"props":1541,"children":1542},{},[1543],{"type":56,"value":1544},"Paste-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.",{"type":50,"tag":470,"props":1546,"children":1548},{"className":472,"code":1547,"language":474,"meta":475,"style":475},"WORKSPACE=\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",[1549],{"type":50,"tag":86,"props":1550,"children":1551},{"__ignoreMap":475},[1552,1584,1610,1636,1659,1681,1727,1757,1793,1801,1827,1835,1844,1880,1894,1908,1916,1924,1961,2012,2044,2069,2099,2127,2152,2172,2180,2189,2332,2340,2349,2383,2392,2401,2410,2419,2428,2437,2446,2455,2464,2473,2482,2491,2500,2509,2518],{"type":50,"tag":481,"props":1553,"children":1554},{"class":483,"line":484},[1555,1560,1564,1569,1574,1579],{"type":50,"tag":481,"props":1556,"children":1557},{"style":498},[1558],{"type":56,"value":1559},"WORKSPACE",{"type":50,"tag":481,"props":1561,"children":1562},{"style":504},[1563],{"type":56,"value":953},{"type":50,"tag":481,"props":1565,"children":1566},{"style":516},[1567],{"type":56,"value":1568},"absolute",{"type":50,"tag":481,"props":1570,"children":1571},{"style":510},[1572],{"type":56,"value":1573}," path",{"type":50,"tag":481,"props":1575,"children":1576},{"style":498},[1577],{"type":56,"value":1578},">            ",{"type":50,"tag":481,"props":1580,"children":1581},{"style":488},[1582],{"type":56,"value":1583},"# mounted identically inside the container\n",{"type":50,"tag":481,"props":1585,"children":1586},{"class":483,"line":494},[1587,1592,1596,1601,1605],{"type":50,"tag":481,"props":1588,"children":1589},{"style":498},[1590],{"type":56,"value":1591},"EXP_DIR",{"type":50,"tag":481,"props":1593,"children":1594},{"style":504},[1595],{"type":56,"value":953},{"type":50,"tag":481,"props":1597,"children":1598},{"style":516},[1599],{"type":56,"value":1600},"experiment_result_dir",{"type":50,"tag":481,"props":1602,"children":1603},{"style":504},[1604],{"type":56,"value":963},{"type":50,"tag":481,"props":1606,"children":1607},{"style":488},[1608],{"type":56,"value":1609},"      # contains inference\u002Finference.csv and train.yaml; must be inside $WORKSPACE\n",{"type":50,"tag":481,"props":1611,"children":1612},{"class":483,"line":542},[1613,1618,1622,1627,1631],{"type":50,"tag":481,"props":1614,"children":1615},{"style":498},[1616],{"type":56,"value":1617},"DATASET_ROOT",{"type":50,"tag":481,"props":1619,"children":1620},{"style":504},[1621],{"type":56,"value":953},{"type":50,"tag":481,"props":1623,"children":1624},{"style":516},[1625],{"type":56,"value":1626},"dataset_root",{"type":50,"tag":481,"props":1628,"children":1629},{"style":504},[1630],{"type":56,"value":963},{"type":50,"tag":481,"props":1632,"children":1633},{"style":488},[1634],{"type":56,"value":1635},"          # image root for inference.csv input_path entries; must be inside $WORKSPACE\n",{"type":50,"tag":481,"props":1637,"children":1638},{"class":483,"line":571},[1639,1644,1649,1654],{"type":50,"tag":481,"props":1640,"children":1641},{"style":498},[1642],{"type":56,"value":1643},"MIN_RECALL",{"type":50,"tag":481,"props":1645,"children":1646},{"style":504},[1647],{"type":56,"value":1648},"=",{"type":50,"tag":481,"props":1650,"children":1651},{"style":516},[1652],{"type":56,"value":1653},"1.0",{"type":50,"tag":481,"props":1655,"children":1656},{"style":488},[1657],{"type":56,"value":1658},"                       # zero-miss default; lower if KPI relaxes\n",{"type":50,"tag":481,"props":1660,"children":1661},{"class":483,"line":581},[1662,1667,1671,1676],{"type":50,"tag":481,"props":1663,"children":1664},{"style":498},[1665],{"type":56,"value":1666},"TOP_K",{"type":50,"tag":481,"props":1668,"children":1669},{"style":504},[1670],{"type":56,"value":1648},{"type":50,"tag":481,"props":1672,"children":1673},{"style":516},[1674],{"type":56,"value":1675},"50",{"type":50,"tag":481,"props":1677,"children":1678},{"style":488},[1679],{"type":56,"value":1680},"                             # per-label augmentation budget\n",{"type":50,"tag":481,"props":1682,"children":1683},{"class":483,"line":627},[1684,1689,1693,1697,1702,1707,1712,1717,1722],{"type":50,"tag":481,"props":1685,"children":1686},{"style":498},[1687],{"type":56,"value":1688},"OUT",{"type":50,"tag":481,"props":1690,"children":1691},{"style":504},[1692],{"type":56,"value":1648},{"type":50,"tag":481,"props":1694,"children":1695},{"style":504},[1696],{"type":56,"value":534},{"type":50,"tag":481,"props":1698,"children":1699},{"style":498},[1700],{"type":56,"value":1701},"$EXP_DIR",{"type":50,"tag":481,"props":1703,"children":1704},{"style":516},[1705],{"type":56,"value":1706},"\u002Frca_results\u002F",{"type":50,"tag":481,"props":1708,"children":1709},{"style":504},[1710],{"type":56,"value":1711},"$(",{"type":50,"tag":481,"props":1713,"children":1714},{"style":510},[1715],{"type":56,"value":1716},"date",{"type":50,"tag":481,"props":1718,"children":1719},{"style":516},[1720],{"type":56,"value":1721}," +%Y-%m-%d_%H%M%S",{"type":50,"tag":481,"props":1723,"children":1724},{"style":504},[1725],{"type":56,"value":1726},")\"\n",{"type":50,"tag":481,"props":1728,"children":1729},{"class":483,"line":665},[1730,1735,1739,1743,1748,1753],{"type":50,"tag":481,"props":1731,"children":1732},{"style":498},[1733],{"type":56,"value":1734},"SPEC",{"type":50,"tag":481,"props":1736,"children":1737},{"style":504},[1738],{"type":56,"value":1648},{"type":50,"tag":481,"props":1740,"children":1741},{"style":504},[1742],{"type":56,"value":534},{"type":50,"tag":481,"props":1744,"children":1745},{"style":498},[1746],{"type":56,"value":1747},"$OUT",{"type":50,"tag":481,"props":1749,"children":1750},{"style":516},[1751],{"type":56,"value":1752},"\u002Fvcn_aoi_spec.yaml",{"type":50,"tag":481,"props":1754,"children":1755},{"style":504},[1756],{"type":56,"value":568},{"type":50,"tag":481,"props":1758,"children":1759},{"class":483,"line":708},[1760,1765,1769,1773,1777,1781,1785,1789],{"type":50,"tag":481,"props":1761,"children":1762},{"style":498},[1763],{"type":56,"value":1764},"IMG",{"type":50,"tag":481,"props":1766,"children":1767},{"style":504},[1768],{"type":56,"value":507},{"type":50,"tag":481,"props":1770,"children":1771},{"style":510},[1772],{"type":56,"value":513},{"type":50,"tag":481,"props":1774,"children":1775},{"style":516},[1776],{"type":56,"value":519},{"type":50,"tag":481,"props":1778,"children":1779},{"style":504},[1780],{"type":56,"value":524},{"type":50,"tag":481,"props":1782,"children":1783},{"style":516},[1784],{"type":56,"value":529},{"type":50,"tag":481,"props":1786,"children":1787},{"style":504},[1788],{"type":56,"value":534},{"type":50,"tag":481,"props":1790,"children":1791},{"style":504},[1792],{"type":56,"value":539},{"type":50,"tag":481,"props":1794,"children":1796},{"class":483,"line":1795},9,[1797],{"type":50,"tag":481,"props":1798,"children":1799},{"emptyLinePlaceholder":575},[1800],{"type":56,"value":578},{"type":50,"tag":481,"props":1802,"children":1804},{"class":483,"line":1803},10,[1805,1810,1815,1819,1823],{"type":50,"tag":481,"props":1806,"children":1807},{"style":510},[1808],{"type":56,"value":1809},"mkdir",{"type":50,"tag":481,"props":1811,"children":1812},{"style":516},[1813],{"type":56,"value":1814}," -p",{"type":50,"tag":481,"props":1816,"children":1817},{"style":504},[1818],{"type":56,"value":524},{"type":50,"tag":481,"props":1820,"children":1821},{"style":498},[1822],{"type":56,"value":1747},{"type":50,"tag":481,"props":1824,"children":1825},{"style":504},[1826],{"type":56,"value":568},{"type":50,"tag":481,"props":1828,"children":1830},{"class":483,"line":1829},11,[1831],{"type":50,"tag":481,"props":1832,"children":1833},{"emptyLinePlaceholder":575},[1834],{"type":56,"value":578},{"type":50,"tag":481,"props":1836,"children":1838},{"class":483,"line":1837},12,[1839],{"type":50,"tag":481,"props":1840,"children":1841},{"style":488},[1842],{"type":56,"value":1843},"# Write the gap-analysis spec for this run\n",{"type":50,"tag":481,"props":1845,"children":1847},{"class":483,"line":1846},13,[1848,1853,1857,1861,1866,1870,1875],{"type":50,"tag":481,"props":1849,"children":1850},{"style":510},[1851],{"type":56,"value":1852},"cat",{"type":50,"tag":481,"props":1854,"children":1855},{"style":504},[1856],{"type":56,"value":596},{"type":50,"tag":481,"props":1858,"children":1859},{"style":504},[1860],{"type":56,"value":524},{"type":50,"tag":481,"props":1862,"children":1863},{"style":498},[1864],{"type":56,"value":1865},"$SPEC",{"type":50,"tag":481,"props":1867,"children":1868},{"style":504},[1869],{"type":56,"value":534},{"type":50,"tag":481,"props":1871,"children":1872},{"style":504},[1873],{"type":56,"value":1874}," \u003C\u003C",{"type":50,"tag":481,"props":1876,"children":1877},{"style":504},[1878],{"type":56,"value":1879},"EOF\n",{"type":50,"tag":481,"props":1881,"children":1883},{"class":483,"line":1882},14,[1884,1889],{"type":50,"tag":481,"props":1885,"children":1886},{"style":516},[1887],{"type":56,"value":1888},"min_recall: ",{"type":50,"tag":481,"props":1890,"children":1891},{"style":498},[1892],{"type":56,"value":1893},"$MIN_RECALL\n",{"type":50,"tag":481,"props":1895,"children":1897},{"class":483,"line":1896},15,[1898,1903],{"type":50,"tag":481,"props":1899,"children":1900},{"style":516},[1901],{"type":56,"value":1902},"top_k_per_label: ",{"type":50,"tag":481,"props":1904,"children":1905},{"style":498},[1906],{"type":56,"value":1907},"$TOP_K\n",{"type":50,"tag":481,"props":1909,"children":1911},{"class":483,"line":1910},16,[1912],{"type":50,"tag":481,"props":1913,"children":1914},{"style":504},[1915],{"type":56,"value":1879},{"type":50,"tag":481,"props":1917,"children":1919},{"class":483,"line":1918},17,[1920],{"type":50,"tag":481,"props":1921,"children":1922},{"emptyLinePlaceholder":575},[1923],{"type":56,"value":578},{"type":50,"tag":481,"props":1925,"children":1927},{"class":483,"line":1926},18,[1928,1932,1937,1942,1947,1952,1957],{"type":50,"tag":481,"props":1929,"children":1930},{"style":510},[1931],{"type":56,"value":19},{"type":50,"tag":481,"props":1933,"children":1934},{"style":516},[1935],{"type":56,"value":1936}," run",{"type":50,"tag":481,"props":1938,"children":1939},{"style":516},[1940],{"type":56,"value":1941}," --gpus",{"type":50,"tag":481,"props":1943,"children":1944},{"style":516},[1945],{"type":56,"value":1946}," all",{"type":50,"tag":481,"props":1948,"children":1949},{"style":516},[1950],{"type":56,"value":1951}," --rm",{"type":50,"tag":481,"props":1953,"children":1954},{"style":516},[1955],{"type":56,"value":1956}," --ipc=host",{"type":50,"tag":481,"props":1958,"children":1959},{"style":498},[1960],{"type":56,"value":705},{"type":50,"tag":481,"props":1962,"children":1964},{"class":483,"line":1963},19,[1965,1970,1974,1979,1983,1987,1991,1996,2000,2004,2008],{"type":50,"tag":481,"props":1966,"children":1967},{"style":516},[1968],{"type":56,"value":1969},"    -v",{"type":50,"tag":481,"props":1971,"children":1972},{"style":504},[1973],{"type":56,"value":524},{"type":50,"tag":481,"props":1975,"children":1976},{"style":498},[1977],{"type":56,"value":1978},"$WORKSPACE",{"type":50,"tag":481,"props":1980,"children":1981},{"style":516},[1982],{"type":56,"value":1235},{"type":50,"tag":481,"props":1984,"children":1985},{"style":498},[1986],{"type":56,"value":1978},{"type":50,"tag":481,"props":1988,"children":1989},{"style":504},[1990],{"type":56,"value":534},{"type":50,"tag":481,"props":1992,"children":1993},{"style":516},[1994],{"type":56,"value":1995}," -w",{"type":50,"tag":481,"props":1997,"children":1998},{"style":504},[1999],{"type":56,"value":524},{"type":50,"tag":481,"props":2001,"children":2002},{"style":498},[2003],{"type":56,"value":1978},{"type":50,"tag":481,"props":2005,"children":2006},{"style":504},[2007],{"type":56,"value":534},{"type":50,"tag":481,"props":2009,"children":2010},{"style":498},[2011],{"type":56,"value":705},{"type":50,"tag":481,"props":2013,"children":2015},{"class":483,"line":2014},20,[2016,2021,2026,2030,2035,2040],{"type":50,"tag":481,"props":2017,"children":2018},{"style":504},[2019],{"type":56,"value":2020},"    \"",{"type":50,"tag":481,"props":2022,"children":2023},{"style":498},[2024],{"type":56,"value":2025},"$IMG",{"type":50,"tag":481,"props":2027,"children":2028},{"style":504},[2029],{"type":56,"value":534},{"type":50,"tag":481,"props":2031,"children":2032},{"style":516},[2033],{"type":56,"value":2034}," gap_analysis",{"type":50,"tag":481,"props":2036,"children":2037},{"style":516},[2038],{"type":56,"value":2039}," vcn_aoi",{"type":50,"tag":481,"props":2041,"children":2042},{"style":498},[2043],{"type":56,"value":705},{"type":50,"tag":481,"props":2045,"children":2047},{"class":483,"line":2046},21,[2048,2053,2057,2061,2065],{"type":50,"tag":481,"props":2049,"children":2050},{"style":516},[2051],{"type":56,"value":2052},"    -e",{"type":50,"tag":481,"props":2054,"children":2055},{"style":504},[2056],{"type":56,"value":524},{"type":50,"tag":481,"props":2058,"children":2059},{"style":498},[2060],{"type":56,"value":1865},{"type":50,"tag":481,"props":2062,"children":2063},{"style":504},[2064],{"type":56,"value":534},{"type":50,"tag":481,"props":2066,"children":2067},{"style":498},[2068],{"type":56,"value":705},{"type":50,"tag":481,"props":2070,"children":2072},{"class":483,"line":2071},22,[2073,2078,2082,2086,2091,2095],{"type":50,"tag":481,"props":2074,"children":2075},{"style":516},[2076],{"type":56,"value":2077},"    inference_results_dir=",{"type":50,"tag":481,"props":2079,"children":2080},{"style":504},[2081],{"type":56,"value":534},{"type":50,"tag":481,"props":2083,"children":2084},{"style":498},[2085],{"type":56,"value":1701},{"type":50,"tag":481,"props":2087,"children":2088},{"style":516},[2089],{"type":56,"value":2090},"\u002Finference\u002Flatest\u002F",{"type":50,"tag":481,"props":2092,"children":2093},{"style":504},[2094],{"type":56,"value":534},{"type":50,"tag":481,"props":2096,"children":2097},{"style":498},[2098],{"type":56,"value":705},{"type":50,"tag":481,"props":2100,"children":2102},{"class":483,"line":2101},23,[2103,2107,2111,2115,2119,2123],{"type":50,"tag":481,"props":2104,"children":2105},{"style":516},[2106],{"type":56,"value":997},{"type":50,"tag":481,"props":2108,"children":2109},{"style":504},[2110],{"type":56,"value":534},{"type":50,"tag":481,"props":2112,"children":2113},{"style":498},[2114],{"type":56,"value":1701},{"type":50,"tag":481,"props":2116,"children":2117},{"style":516},[2118],{"type":56,"value":1020},{"type":50,"tag":481,"props":2120,"children":2121},{"style":504},[2122],{"type":56,"value":534},{"type":50,"tag":481,"props":2124,"children":2125},{"style":498},[2126],{"type":56,"value":705},{"type":50,"tag":481,"props":2128,"children":2130},{"class":483,"line":2129},24,[2131,2135,2139,2144,2148],{"type":50,"tag":481,"props":2132,"children":2133},{"style":516},[2134],{"type":56,"value":1032},{"type":50,"tag":481,"props":2136,"children":2137},{"style":504},[2138],{"type":56,"value":534},{"type":50,"tag":481,"props":2140,"children":2141},{"style":498},[2142],{"type":56,"value":2143},"$DATASET_ROOT",{"type":50,"tag":481,"props":2145,"children":2146},{"style":504},[2147],{"type":56,"value":534},{"type":50,"tag":481,"props":2149,"children":2150},{"style":498},[2151],{"type":56,"value":705},{"type":50,"tag":481,"props":2153,"children":2155},{"class":483,"line":2154},25,[2156,2160,2164,2168],{"type":50,"tag":481,"props":2157,"children":2158},{"style":516},[2159],{"type":56,"value":1062},{"type":50,"tag":481,"props":2161,"children":2162},{"style":504},[2163],{"type":56,"value":534},{"type":50,"tag":481,"props":2165,"children":2166},{"style":498},[2167],{"type":56,"value":1747},{"type":50,"tag":481,"props":2169,"children":2170},{"style":504},[2171],{"type":56,"value":568},{"type":50,"tag":481,"props":2173,"children":2175},{"class":483,"line":2174},26,[2176],{"type":50,"tag":481,"props":2177,"children":2178},{"emptyLinePlaceholder":575},[2179],{"type":56,"value":578},{"type":50,"tag":481,"props":2181,"children":2183},{"class":483,"line":2182},27,[2184],{"type":50,"tag":481,"props":2185,"children":2186},{"style":488},[2187],{"type":56,"value":2188},"# Container writes as root with --user dropped; chown back to host UID if needed.\n",{"type":50,"tag":481,"props":2190,"children":2192},{"class":483,"line":2191},28,[2193,2197,2201,2205,2210,2214,2218,2223,2227,2232,2237,2242,2247,2252,2257,2262,2266,2270,2274,2279,2284,2288,2293,2297,2302,2307,2311,2315,2319,2323,2327],{"type":50,"tag":481,"props":2194,"children":2195},{"style":510},[2196],{"type":56,"value":19},{"type":50,"tag":481,"props":2198,"children":2199},{"style":516},[2200],{"type":56,"value":1936},{"type":50,"tag":481,"props":2202,"children":2203},{"style":516},[2204],{"type":56,"value":1951},{"type":50,"tag":481,"props":2206,"children":2207},{"style":516},[2208],{"type":56,"value":2209}," -v",{"type":50,"tag":481,"props":2211,"children":2212},{"style":504},[2213],{"type":56,"value":524},{"type":50,"tag":481,"props":2215,"children":2216},{"style":498},[2217],{"type":56,"value":1978},{"type":50,"tag":481,"props":2219,"children":2220},{"style":516},[2221],{"type":56,"value":2222},":\u002Fw",{"type":50,"tag":481,"props":2224,"children":2225},{"style":504},[2226],{"type":56,"value":534},{"type":50,"tag":481,"props":2228,"children":2229},{"style":516},[2230],{"type":56,"value":2231}," alpine",{"type":50,"tag":481,"props":2233,"children":2234},{"style":516},[2235],{"type":56,"value":2236}," chown",{"type":50,"tag":481,"props":2238,"children":2239},{"style":516},[2240],{"type":56,"value":2241}," -R",{"type":50,"tag":481,"props":2243,"children":2244},{"style":504},[2245],{"type":56,"value":2246}," \"$(",{"type":50,"tag":481,"props":2248,"children":2249},{"style":510},[2250],{"type":56,"value":2251},"id",{"type":50,"tag":481,"props":2253,"children":2254},{"style":516},[2255],{"type":56,"value":2256}," -u",{"type":50,"tag":481,"props":2258,"children":2259},{"style":504},[2260],{"type":56,"value":2261},")",{"type":50,"tag":481,"props":2263,"children":2264},{"style":516},[2265],{"type":56,"value":1235},{"type":50,"tag":481,"props":2267,"children":2268},{"style":504},[2269],{"type":56,"value":1711},{"type":50,"tag":481,"props":2271,"children":2272},{"style":510},[2273],{"type":56,"value":2251},{"type":50,"tag":481,"props":2275,"children":2276},{"style":516},[2277],{"type":56,"value":2278}," -g",{"type":50,"tag":481,"props":2280,"children":2281},{"style":504},[2282],{"type":56,"value":2283},")\"",{"type":50,"tag":481,"props":2285,"children":2286},{"style":504},[2287],{"type":56,"value":524},{"type":50,"tag":481,"props":2289,"children":2290},{"style":516},[2291],{"type":56,"value":2292},"\u002Fw\u002F",{"type":50,"tag":481,"props":2294,"children":2295},{"style":504},[2296],{"type":56,"value":1711},{"type":50,"tag":481,"props":2298,"children":2299},{"style":510},[2300],{"type":56,"value":2301},"realpath",{"type":50,"tag":481,"props":2303,"children":2304},{"style":516},[2305],{"type":56,"value":2306}," --relative-to=",{"type":50,"tag":481,"props":2308,"children":2309},{"style":504},[2310],{"type":56,"value":534},{"type":50,"tag":481,"props":2312,"children":2313},{"style":498},[2314],{"type":56,"value":1978},{"type":50,"tag":481,"props":2316,"children":2317},{"style":504},[2318],{"type":56,"value":534},{"type":50,"tag":481,"props":2320,"children":2321},{"style":504},[2322],{"type":56,"value":524},{"type":50,"tag":481,"props":2324,"children":2325},{"style":498},[2326],{"type":56,"value":1747},{"type":50,"tag":481,"props":2328,"children":2329},{"style":504},[2330],{"type":56,"value":2331},"\")\"\n",{"type":50,"tag":481,"props":2333,"children":2335},{"class":483,"line":2334},29,[2336],{"type":50,"tag":481,"props":2337,"children":2338},{"emptyLinePlaceholder":575},[2339],{"type":56,"value":578},{"type":50,"tag":481,"props":2341,"children":2343},{"class":483,"line":2342},30,[2344],{"type":50,"tag":481,"props":2345,"children":2346},{"style":488},[2347],{"type":56,"value":2348},"# Sanity print so the script-check hook sees real numbers\n",{"type":50,"tag":481,"props":2350,"children":2352},{"class":483,"line":2351},31,[2353,2357,2362,2366,2370,2374,2378],{"type":50,"tag":481,"props":2354,"children":2355},{"style":510},[2356],{"type":56,"value":513},{"type":50,"tag":481,"props":2358,"children":2359},{"style":516},[2360],{"type":56,"value":2361}," -",{"type":50,"tag":481,"props":2363,"children":2364},{"style":504},[2365],{"type":56,"value":524},{"type":50,"tag":481,"props":2367,"children":2368},{"style":498},[2369],{"type":56,"value":1747},{"type":50,"tag":481,"props":2371,"children":2372},{"style":504},[2373],{"type":56,"value":534},{"type":50,"tag":481,"props":2375,"children":2376},{"style":504},[2377],{"type":56,"value":1874},{"type":50,"tag":481,"props":2379,"children":2380},{"style":504},[2381],{"type":56,"value":2382}," 'PYEOF'\n",{"type":50,"tag":481,"props":2384,"children":2386},{"class":483,"line":2385},32,[2387],{"type":50,"tag":481,"props":2388,"children":2389},{"style":516},[2390],{"type":56,"value":2391},"import json, os, sys\n",{"type":50,"tag":481,"props":2393,"children":2395},{"class":483,"line":2394},33,[2396],{"type":50,"tag":481,"props":2397,"children":2398},{"style":516},[2399],{"type":56,"value":2400},"out = sys.argv[1]\n",{"type":50,"tag":481,"props":2402,"children":2404},{"class":483,"line":2403},34,[2405],{"type":50,"tag":481,"props":2406,"children":2407},{"style":516},[2408],{"type":56,"value":2409},"unreachable = os.path.join(out, \"unreachable_kpi.txt\")\n",{"type":50,"tag":481,"props":2411,"children":2413},{"class":483,"line":2412},35,[2414],{"type":50,"tag":481,"props":2415,"children":2416},{"style":516},[2417],{"type":56,"value":2418},"if os.path.isfile(unreachable):\n",{"type":50,"tag":481,"props":2420,"children":2422},{"class":483,"line":2421},36,[2423],{"type":50,"tag":481,"props":2424,"children":2425},{"style":516},[2426],{"type":56,"value":2427},"    print(\"KPI UNREACHABLE — see\", unreachable)\n",{"type":50,"tag":481,"props":2429,"children":2431},{"class":483,"line":2430},37,[2432],{"type":50,"tag":481,"props":2433,"children":2434},{"style":516},[2435],{"type":56,"value":2436},"    sys.exit(0)\n",{"type":50,"tag":481,"props":2438,"children":2440},{"class":483,"line":2439},38,[2441],{"type":50,"tag":481,"props":2442,"children":2443},{"style":516},[2444],{"type":56,"value":2445},"with open(os.path.join(out, \"threshold.txt\")) as f:\n",{"type":50,"tag":481,"props":2447,"children":2449},{"class":483,"line":2448},39,[2450],{"type":50,"tag":481,"props":2451,"children":2452},{"style":516},[2453],{"type":56,"value":2454},"    print(\"threshold:\", f.read().strip())\n",{"type":50,"tag":481,"props":2456,"children":2458},{"class":483,"line":2457},40,[2459],{"type":50,"tag":481,"props":2460,"children":2461},{"style":516},[2462],{"type":56,"value":2463},"with open(os.path.join(out, \"metrics.json\")) as f:\n",{"type":50,"tag":481,"props":2465,"children":2467},{"class":483,"line":2466},41,[2468],{"type":50,"tag":481,"props":2469,"children":2470},{"style":516},[2471],{"type":56,"value":2472},"    m = json.load(f)\n",{"type":50,"tag":481,"props":2474,"children":2476},{"class":483,"line":2475},42,[2477],{"type":50,"tag":481,"props":2478,"children":2479},{"style":516},[2480],{"type":56,"value":2481},"print(f\"precision={m['precision']:.4f} recall={m['recall']:.4f} f1={m['f1']:.4f}\")\n",{"type":50,"tag":481,"props":2483,"children":2485},{"class":483,"line":2484},43,[2486],{"type":50,"tag":481,"props":2487,"children":2488},{"style":516},[2489],{"type":56,"value":2490},"import pandas as pd\n",{"type":50,"tag":481,"props":2492,"children":2494},{"class":483,"line":2493},44,[2495],{"type":50,"tag":481,"props":2496,"children":2497},{"style":516},[2498],{"type":56,"value":2499},"df = pd.read_parquet(os.path.join(out, \"kpi_gaps.parquet\"))\n",{"type":50,"tag":481,"props":2501,"children":2503},{"class":483,"line":2502},45,[2504],{"type":50,"tag":481,"props":2505,"children":2506},{"style":516},[2507],{"type":56,"value":2508},"print(f\"kpi_gaps.parquet: rows={len(df)}, cols={list(df.columns)}\")\n",{"type":50,"tag":481,"props":2510,"children":2512},{"class":483,"line":2511},46,[2513],{"type":50,"tag":481,"props":2514,"children":2515},{"style":516},[2516],{"type":56,"value":2517},"print(df['label'].value_counts())\n",{"type":50,"tag":481,"props":2519,"children":2521},{"class":483,"line":2520},47,[2522],{"type":50,"tag":481,"props":2523,"children":2524},{"style":504},[2525],{"type":56,"value":2526},"PYEOF\n",{"type":50,"tag":234,"props":2528,"children":2529},{},[],{"type":50,"tag":238,"props":2531,"children":2533},{"id":2532},"outputs",[2534],{"type":56,"value":2535},"Outputs",{"type":50,"tag":59,"props":2537,"children":2538},{},[2539,2541,2547,2549,2555],{"type":56,"value":2540},"Write everything into a timestamped folder under the experiment result directory. The container's outputs go straight there; the visual spot-check writes ",{"type":50,"tag":86,"props":2542,"children":2544},{"className":2543},[],[2545],{"type":56,"value":2546},"rca_images\u002F",{"type":56,"value":2548},"; any runtime packaging hook may add session\u002Fconfig capture artifacts after ",{"type":50,"tag":86,"props":2550,"children":2552},{"className":2551},[],[2553],{"type":56,"value":2554},"RCA_Report.md",{"type":56,"value":2556}," is written.",{"type":50,"tag":470,"props":2558,"children":2562},{"className":2559,"code":2561,"language":56},[2560],"language-text","\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",[2563],{"type":50,"tag":86,"props":2564,"children":2565},{"__ignoreMap":475},[2566],{"type":56,"value":2561},{"type":50,"tag":59,"props":2568,"children":2569},{},[2570,2572,2578],{"type":56,"value":2571},"At the start of the run, get the real timestamp by running ",{"type":50,"tag":86,"props":2573,"children":2575},{"className":2574},[],[2576],{"type":56,"value":2577},"date +%Y-%m-%d_%H%M%S",{"type":56,"value":2579}," in Bash. Do NOT hardcode or guess. If the user specifies a custom output path, use that instead but maintain the same internal structure.",{"type":50,"tag":234,"props":2581,"children":2582},{},[],{"type":50,"tag":238,"props":2584,"children":2586},{"id":2585},"common-pitfalls",[2587],{"type":56,"value":2588},"Common pitfalls",{"type":50,"tag":59,"props":2590,"children":2591},{},[2592,2594,2611,2613,2618,2620,2625],{"type":56,"value":2593},"The single most consequential failure mode is ",{"type":50,"tag":65,"props":2595,"children":2596},{},[2597,2599,2604,2606],{"type":56,"value":2598},"forgetting ",{"type":50,"tag":86,"props":2600,"children":2602},{"className":2601},[],[2603],{"type":56,"value":390},{"type":56,"value":2605}," when ",{"type":50,"tag":86,"props":2607,"children":2609},{"className":2608},[],[2610],{"type":56,"value":406},{"type":56,"value":2612},": at that recall the chosen threshold sits at or below every NO_PASS score, so without ",{"type":50,"tag":86,"props":2614,"children":2616},{"className":2615},[],[2617],{"type":56,"value":390},{"type":56,"value":2619}," 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 ",{"type":50,"tag":86,"props":2621,"children":2623},{"className":2622},[],[2624],{"type":56,"value":390},{"type":56,"value":2626}," (default 50) in the spec or as a Hydra override.",{"type":50,"tag":59,"props":2628,"children":2629},{},[2630,2631,2637,2639,2644,2646,2651,2653,2658,2660,2665,2667,2673,2675,2680,2682,2687,2689,2694,2696,2702,2704,2709,2711,2716],{"type":56,"value":851},{"type":50,"tag":86,"props":2632,"children":2634},{"className":2633},[],[2635],{"type":56,"value":2636},"references\u002Fpitfalls.md",{"type":56,"value":2638}," for the complete checklist, covering: forgetting ",{"type":50,"tag":86,"props":2640,"children":2642},{"className":2641},[],[2643],{"type":56,"value":390},{"type":56,"value":2645},"; passing ",{"type":50,"tag":86,"props":2647,"children":2649},{"className":2648},[],[2650],{"type":56,"value":865},{"type":56,"value":2652},"; calling with only Hydra overrides (no ",{"type":50,"tag":86,"props":2654,"children":2656},{"className":2655},[],[2657],{"type":56,"value":834},{"type":56,"value":2659},"); spec file outside ",{"type":50,"tag":86,"props":2661,"children":2663},{"className":2662},[],[2664],{"type":56,"value":1978},{"type":56,"value":2666},"; spec file with unresolved ",{"type":50,"tag":86,"props":2668,"children":2670},{"className":2669},[],[2671],{"type":56,"value":2672},"???",{"type":56,"value":2674}," sentinels; image not pulled \u002F wrong tag; path-mount mismatch; ",{"type":50,"tag":86,"props":2676,"children":2678},{"className":2677},[],[2679],{"type":56,"value":1211},{"type":56,"value":2681}," written; ",{"type":50,"tag":86,"props":2683,"children":2685},{"className":2684},[],[2686],{"type":56,"value":772},{"type":56,"value":2688}," missing required columns; train YAML missing ",{"type":50,"tag":86,"props":2690,"children":2692},{"className":2691},[],[2693],{"type":56,"value":332},{"type":56,"value":2695}," or ",{"type":50,"tag":86,"props":2697,"children":2699},{"className":2698},[],[2700],{"type":56,"value":2701},"image_ext",{"type":56,"value":2703},"; ",{"type":50,"tag":86,"props":2705,"children":2707},{"className":2706},[],[2708],{"type":56,"value":365},{"type":56,"value":2710}," not matching ",{"type":50,"tag":86,"props":2712,"children":2714},{"className":2713},[],[2715],{"type":56,"value":272},{"type":56,"value":2717}," prefixes; and no GPU detected from inside the container.",{"type":50,"tag":234,"props":2719,"children":2720},{},[],{"type":50,"tag":238,"props":2722,"children":2724},{"id":2723},"report-structure",[2725],{"type":56,"value":2726},"Report Structure",{"type":50,"tag":59,"props":2728,"children":2729},{},[2730,2732,2737,2739,2745,2747,2752],{"type":56,"value":2731},"Write ",{"type":50,"tag":86,"props":2733,"children":2735},{"className":2734},[],[2736],{"type":56,"value":2554},{"type":56,"value":2738}," 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 ",{"type":50,"tag":86,"props":2740,"children":2742},{"className":2741},[],[2743],{"type":56,"value":2744},"references\u002Foutput-template.md",{"type":56,"value":2746},". When ",{"type":50,"tag":86,"props":2748,"children":2750},{"className":2749},[],[2751],{"type":56,"value":1211},{"type":56,"value":2753}," 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.",{"type":50,"tag":234,"props":2755,"children":2756},{},[],{"type":50,"tag":238,"props":2758,"children":2760},{"id":2759},"execution-order",[2761],{"type":56,"value":2762},"Execution Order",{"type":50,"tag":245,"props":2764,"children":2765},{},[2766,2815,2834,2874,2917,2928,2946],{"type":50,"tag":249,"props":2767,"children":2768},{},[2769,2771,2776,2778,2783,2785,2791,2793,2799,2800,2805,2807,2813],{"type":56,"value":2770},"Resolve ",{"type":50,"tag":86,"props":2772,"children":2774},{"className":2773},[],[2775],{"type":56,"value":501},{"type":56,"value":2777}," from ",{"type":50,"tag":86,"props":2779,"children":2781},{"className":2780},[],[2782],{"type":56,"value":115},{"type":56,"value":2784}," (",{"type":50,"tag":86,"props":2786,"children":2788},{"className":2787},[],[2789],{"type":56,"value":2790},"images.tao_toolkit.data_services",{"type":56,"value":2792},"), then run ",{"type":50,"tag":86,"props":2794,"children":2796},{"className":2795},[],[2797],{"type":56,"value":2798},"docker info",{"type":56,"value":209},{"type":50,"tag":86,"props":2801,"children":2803},{"className":2802},[],[2804],{"type":56,"value":633},{"type":56,"value":2806},", and ",{"type":50,"tag":86,"props":2808,"children":2810},{"className":2809},[],[2811],{"type":56,"value":2812},"docker image inspect \"$DS_IMAGE\"",{"type":56,"value":2814}," (pulling if missing) once to confirm the environment. Abort with a clear message if any fail.",{"type":50,"tag":249,"props":2816,"children":2817},{},[2818,2820,2825,2827,2833],{"type":56,"value":2819},"Run ",{"type":50,"tag":86,"props":2821,"children":2823},{"className":2822},[],[2824],{"type":56,"value":2577},{"type":56,"value":2826}," to get the timestamp; create ",{"type":50,"tag":86,"props":2828,"children":2830},{"className":2829},[],[2831],{"type":56,"value":2832},"\u003Cexperiment_result_dir>\u002Frca_results\u002F\u003Ctimestamp>\u002F",{"type":56,"value":232},{"type":50,"tag":249,"props":2835,"children":2836},{},[2837,2838,2844,2846,2851,2852,2857,2859,2864,2866,2872],{"type":56,"value":2731},{"type":50,"tag":86,"props":2839,"children":2841},{"className":2840},[],[2842],{"type":56,"value":2843},"vcn_aoi_spec.yaml",{"type":56,"value":2845}," into the timestamped dir with ",{"type":50,"tag":86,"props":2847,"children":2849},{"className":2848},[],[2850],{"type":56,"value":383},{"type":56,"value":1186},{"type":50,"tag":86,"props":2853,"children":2855},{"className":2854},[],[2856],{"type":56,"value":390},{"type":56,"value":2858}," filled in. Keep it under ",{"type":50,"tag":86,"props":2860,"children":2862},{"className":2861},[],[2863],{"type":56,"value":1978},{"type":56,"value":2865}," so the ",{"type":50,"tag":86,"props":2867,"children":2869},{"className":2868},[],[2870],{"type":56,"value":2871},"-e",{"type":56,"value":2873}," path resolves inside the container.",{"type":50,"tag":249,"props":2875,"children":2876},{},[2877,2878,2884,2886,2891,2892,2897,2898,2903,2904,2909,2910,2915],{"type":56,"value":2819},{"type":50,"tag":86,"props":2879,"children":2881},{"className":2880},[],[2882],{"type":56,"value":2883},"docker run … \"$DS_IMAGE\" gap_analysis vcn_aoi -e vcn_aoi_spec.yaml inference_results_dir=… train_config=… kpi_media_path=… output_dir=…",{"type":56,"value":2885},". The container writes ",{"type":50,"tag":86,"props":2887,"children":2889},{"className":2888},[],[2890],{"type":56,"value":230},{"type":56,"value":209},{"type":50,"tag":86,"props":2893,"children":2895},{"className":2894},[],[2896],{"type":56,"value":1317},{"type":56,"value":209},{"type":50,"tag":86,"props":2899,"children":2901},{"className":2900},[],[2902],{"type":56,"value":1334},{"type":56,"value":209},{"type":50,"tag":86,"props":2905,"children":2907},{"className":2906},[],[2908],{"type":56,"value":1388},{"type":56,"value":1213},{"type":50,"tag":86,"props":2911,"children":2913},{"className":2912},[],[2914],{"type":56,"value":222},{"type":56,"value":2916},". Print the chosen threshold and kept-row counts to stdout so the script-check hook can verify the run produced output.",{"type":50,"tag":249,"props":2918,"children":2919},{},[2920,2921,2926],{"type":56,"value":1198},{"type":50,"tag":86,"props":2922,"children":2924},{"className":2923},[],[2925],{"type":56,"value":1211},{"type":56,"value":2927}," exists, skip Step 6 and write the abridged report. Otherwise continue.",{"type":50,"tag":249,"props":2929,"children":2930},{},[2931,2933,2938,2940,2945],{"type":56,"value":2932},"Pick 10 weak samples (5 weakest PASS + 5 weakest NO_PASS) from ",{"type":50,"tag":86,"props":2934,"children":2936},{"className":2935},[],[2937],{"type":56,"value":230},{"type":56,"value":2939},", view each test image with Read, classify, and copy each into ",{"type":50,"tag":86,"props":2941,"children":2943},{"className":2942},[],[2944],{"type":56,"value":2546},{"type":56,"value":232},{"type":50,"tag":249,"props":2947,"children":2948},{},[2949,2950,2955],{"type":56,"value":2731},{"type":50,"tag":86,"props":2951,"children":2953},{"className":2952},[],[2954],{"type":56,"value":2554},{"type":56,"value":2956}," last — writing it triggers the packaging hook, which copies session logs and skill config alongside.",{"type":50,"tag":2958,"props":2959,"children":2960},"style",{},[2961],{"type":56,"value":2962},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2964,"total":3064},[2965,2980,2994,3008,3020,3037,3050],{"slug":2966,"name":2966,"fn":2967,"description":2968,"org":2969,"tags":2970,"stars":23,"repoUrl":24,"updatedAt":2979},"accelerated-computing-cudf","accelerate data processing with cuDF","Official NVIDIA-authored guidance for NVIDIA cuDF GPU DataFrames, pandas acceleration, dask-cuDF, ETL, joins, groupby, CSV\u002FParquet I\u002FO, nullable semantics, and multi-GPU DataFrame workloads.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2971,2972,2975,2976],{"name":13,"slug":14,"type":15},{"name":2973,"slug":2974,"type":15},"Data Engineering","data-engineering",{"name":9,"slug":8,"type":15},{"name":2977,"slug":2978,"type":15},"Performance","performance","2026-07-14T05:28:43.176466",{"slug":2981,"name":2981,"fn":2982,"description":2983,"org":2984,"tags":2985,"stars":23,"repoUrl":24,"updatedAt":2993},"aiq-deploy","deploy and manage NVIDIA AI-Q infrastructure","Use when asked to install, deploy, run, validate, troubleshoot, or stop NVIDIA AI-Q Blueprint infrastructure.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2986,2989,2992],{"name":2987,"slug":2988,"type":15},"Deployment","deployment",{"name":2990,"slug":2991,"type":15},"Infrastructure","infrastructure",{"name":9,"slug":8,"type":15},"2026-07-14T05:29:06.667109",{"slug":2995,"name":2995,"fn":2996,"description":2997,"org":2998,"tags":2999,"stars":23,"repoUrl":24,"updatedAt":3007},"aiq-research","conduct deep research with AI-Q","Use when asked to run deep research or AI-Q research through a reachable NVIDIA AI-Q Blueprint backend.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3000,3003,3004],{"name":3001,"slug":3002,"type":15},"Agents","agents",{"name":9,"slug":8,"type":15},{"name":3005,"slug":3006,"type":15},"Research","research","2026-07-14T05:28:06.816956",{"slug":3009,"name":3009,"fn":3010,"description":3011,"org":3012,"tags":3013,"stars":23,"repoUrl":24,"updatedAt":3019},"amc-run-sample-calibration","run AMC sample dataset calibration","Run end-to-end calibration on the shipped sample dataset (sdg_08_2_sample_data_010926.zip) against a running AMC microservice. Use when user says 'test sample dataset', 'run sample calibration', 'verify AMC install', or 'launch and test'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3014,3015,3016],{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"name":3017,"slug":3018,"type":15},"Testing","testing","2026-07-17T05:29:03.913266",{"slug":3021,"name":3021,"fn":3022,"description":3023,"org":3024,"tags":3025,"stars":23,"repoUrl":24,"updatedAt":3036},"amc-run-video-calibration","calibrate video datasets with AutoMagicCalib","Calibrate a new dataset from pre-recorded video files via the AutoMagicCalib REST API. Use when user has local MP4s and says 'calibrate my videos', 'run AMC on these videos', or similar. For RTSP\u002Flive streams, use amc-run-rtsp-calibration instead.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3026,3029,3032,3033],{"name":3027,"slug":3028,"type":15},"Automation","automation",{"name":3030,"slug":3031,"type":15},"Imaging","imaging",{"name":9,"slug":8,"type":15},{"name":3034,"slug":3035,"type":15},"Video","video","2026-07-17T05:28:53.905004",{"slug":3038,"name":3038,"fn":3039,"description":3040,"org":3041,"tags":3042,"stars":23,"repoUrl":24,"updatedAt":3049},"amc-setup-calibration-stack","deploy AutoMagicCalib microservice with Docker","Launch AutoMagicCalib microservice and web UI from NGC release images via Docker Compose. Use when user says 'deploy auto calibration', 'launch auto calibration', 'launch AMC', 'start MS+UI', or 'set up auto-magic-calib'. Requires NGC API key.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3043,3044,3045,3046],{"name":2987,"slug":2988,"type":15},{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"name":3047,"slug":3048,"type":15},"Operations","operations","2026-07-17T05:28:56.913999",{"slug":3051,"name":3051,"fn":3052,"description":3053,"org":3054,"tags":3055,"stars":23,"repoUrl":24,"updatedAt":3063},"cudaq-guide","develop quantum applications with CUDA-Q","CUDA-Q onboarding guide for installation, test programs, GPU simulation, QPU hardware, and quantum applications.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3056,3057,3060],{"name":9,"slug":8,"type":15},{"name":3058,"slug":3059,"type":15},"Quantum Computing","quantum-computing",{"name":3061,"slug":3062,"type":15},"Simulation","simulation","2026-07-14T05:26:58.898253",305,{"items":3066,"total":3217},[3067,3085,3101,3112,3124,3138,3151,3165,3176,3185,3199,3208],{"slug":3068,"name":3068,"fn":3069,"description":3070,"org":3071,"tags":3072,"stars":3082,"repoUrl":3083,"updatedAt":3084},"nemoclaw-user-guide","retrieve NemoClaw documentation and configuration","Guides human users' AI agents to the NemoClaw docs MCP server and canonical Fern documentation in Markdown form. Use when users ask how to install, configure, operate, troubleshoot, secure, or learn NemoClaw with an AI coding assistant. Trigger keywords - nemoclaw docs, use nemoclaw with ai agent, nemoclaw mcp docs, nemoclaw install help, nemoclaw quickstart, nemoclaw markdown docs, llms.txt, agent skills.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3073,3076,3079],{"name":3074,"slug":3075,"type":15},"Documentation","documentation",{"name":3077,"slug":3078,"type":15},"MCP","mcp",{"name":3080,"slug":3081,"type":15},"Search","search",21777,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FNemoClaw","2026-07-20T06:00:01.461044",{"slug":3086,"name":3086,"fn":3087,"description":3088,"org":3089,"tags":3090,"stars":3098,"repoUrl":3099,"updatedAt":3100},"mcore-build-and-dependency","manage Megatron-LM development environments","Container-based dev environment setup and dependency management for Megatron-LM. Covers acquiring and launching the CI container, uv package management, and updating uv.lock.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3091,3094,3095],{"name":3092,"slug":3093,"type":15},"Containers","containers",{"name":2987,"slug":2988,"type":15},{"name":3096,"slug":3097,"type":15},"Python","python",17049,"https:\u002F\u002Fgithub.com\u002FNVIDIA\u002FMegatron-LM","2026-07-27T06:06:11.249662",{"slug":3102,"name":3102,"fn":3103,"description":3104,"org":3105,"tags":3106,"stars":3098,"repoUrl":3099,"updatedAt":3111},"mcore-bump-base-image","update NVIDIA PyTorch base images","Bump the NVIDIA PyTorch base image (`nvcr.io\u002Fnvidia\u002Fpytorch:YY.MM-py3`) used by Megatron-LM CI. Covers the two pin sites (GitHub CI in `docker\u002F.ngc_version.dev` and GitLab CI in `.gitlab\u002Fstages\u002F01.build.yml`), the post-bump CI loop (re-run functional tests, refresh golden values, mark broken tests), and the gotchas that bit PRs",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3107,3110],{"name":3108,"slug":3109,"type":15},"CI\u002FCD","ci-cd",{"name":2987,"slug":2988,"type":15},"2026-07-14T05:25:59.97109",{"slug":3113,"name":3113,"fn":3114,"description":3115,"org":3116,"tags":3117,"stars":3098,"repoUrl":3099,"updatedAt":3123},"mcore-cicd","manage CI\u002FCD pipelines for Megatron-LM","CI\u002FCD reference for Megatron-LM. Covers CI pipeline structure, PR scope labels, triggering internal GitLab CI (which force-pushes the current branch to a pull-request\u002FBRANCH ref — always dry-run and verify the destination first; never run against shared or protected branches), and CI failure investigation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3118,3119,3120],{"name":3108,"slug":3109,"type":15},{"name":2987,"slug":2988,"type":15},{"name":3121,"slug":3122,"type":15},"GitHub","github","2026-07-27T06:06:12.278222",{"slug":3125,"name":3125,"fn":3126,"description":3127,"org":3128,"tags":3129,"stars":3098,"repoUrl":3099,"updatedAt":3137},"mcore-create-issue","investigate CI failures and create issues","Investigate a failing GitHub Actions run or job and create a GitHub issue for the failure.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3130,3133,3134],{"name":3131,"slug":3132,"type":15},"Debugging","debugging",{"name":3121,"slug":3122,"type":15},{"name":3135,"slug":3136,"type":15},"Triage","triage","2026-07-14T05:25:57.442089",{"slug":3139,"name":3139,"fn":3140,"description":3141,"org":3142,"tags":3143,"stars":3098,"repoUrl":3099,"updatedAt":3150},"mcore-linting-and-formatting","lint and format Megatron-LM code","Linting and formatting for Megatron-LM. Covers running autoformat.sh, tools (ruff, black, isort, pylint, mypy), and code style rules.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3144,3147],{"name":3145,"slug":3146,"type":15},"Best Practices","best-practices",{"name":3148,"slug":3149,"type":15},"Code Analysis","code-analysis","2026-07-14T05:25:56.18433",{"slug":3152,"name":3152,"fn":3153,"description":3154,"org":3155,"tags":3156,"stars":3098,"repoUrl":3099,"updatedAt":3164},"mcore-migrate-gpt-to-hybrid","migrate Megatron-LM models to HybridModel","Migration guide for moving Megatron Core GPTModel checkpoints, model providers, training commands, and layer mappings to HybridModel.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3157,3160,3163],{"name":3158,"slug":3159,"type":15},"Machine Learning","machine-learning",{"name":3161,"slug":3162,"type":15},"Migration","migration",{"name":9,"slug":8,"type":15},"2026-07-17T06:07:11.777011",{"slug":3166,"name":3166,"fn":3167,"description":3168,"org":3169,"tags":3170,"stars":3098,"repoUrl":3099,"updatedAt":3175},"mcore-onboard-gb200-1node-tests","onboard functional tests for GB200","Onboard 1-node GitHub MR functional tests for GB200 from existing mr-scoped 2-node tests.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3171,3174],{"name":3172,"slug":3173,"type":15},"QA","qa",{"name":3017,"slug":3018,"type":15},"2026-07-14T05:25:53.673039",{"slug":3177,"name":3177,"fn":3178,"description":3179,"org":3180,"tags":3181,"stars":3098,"repoUrl":3099,"updatedAt":3184},"mcore-run-on-slurm","launch distributed training jobs on SLURM","How to launch distributed Megatron-LM training jobs on a SLURM cluster. Covers a minimal sbatch skeleton, environment-variable setup for torch.distributed.run, CUDA_DEVICE_MAX_CONNECTIONS rules across hardware and parallelism modes, container conventions, monitoring, and per-rank failure diagnosis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3182,3183],{"name":2987,"slug":2988,"type":15},{"name":2990,"slug":2991,"type":15},"2026-07-14T05:25:49.362534",{"slug":3186,"name":3186,"fn":3187,"description":3188,"org":3189,"tags":3190,"stars":3098,"repoUrl":3099,"updatedAt":3198},"mcore-split-pr","split pull requests to reduce review load","Split a PR into multiple PRs to reduce the number of required CODEOWNERS reviewer groups.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3191,3194,3195],{"name":3192,"slug":3193,"type":15},"Code Review","code-review",{"name":3121,"slug":3122,"type":15},{"name":3196,"slug":3197,"type":15},"Pull Requests","pull-requests","2026-07-14T05:26:01.226578",{"slug":3200,"name":3200,"fn":3201,"description":3202,"org":3203,"tags":3204,"stars":3098,"repoUrl":3099,"updatedAt":3207},"mcore-testing","run and manage Megatron-LM tests","Test system for Megatron-LM. Covers test layout, recipe YAML structure, adding and running unit and functional tests, golden values, marker filters, and CI parity.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3205,3206],{"name":3172,"slug":3173,"type":15},{"name":3017,"slug":3018,"type":15},"2026-07-14T05:25:54.928983",{"slug":3209,"name":3209,"fn":3210,"description":3211,"org":3212,"tags":3213,"stars":3098,"repoUrl":3099,"updatedAt":3216},"nightly-sync","manage nightly main-to-dev sync workflows","Domain knowledge for the nightly main-to-dev sync workflow. Covers merge strategy, CI architecture, failure investigation, and known issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3214,3215],{"name":3027,"slug":3028,"type":15},{"name":3108,"slug":3109,"type":15},"2026-07-30T05:29:03.275638",496]