[
 {
  "id": "T01",
  "target": "bestpractice_pdf_to_markdown",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "### Cause of the Crash\nOn Apple Silicon, Docling's **RT-DETR V2** model calls `torch.float64` operations during the layout detection phase. Because PyTorch's MPS (Metal Performance Shaders) backend does not support `torch.float64`, the conversion crashes.\n\n### Workaround\nPass the **`--device cpu`** flag to run Docling explicitly on the CPU rather than the MPS backend.\n\nExample command:\n```bash\ndocling input.pdf --to md --device cpu --output output_dir\n```\n\n*(Note: For text-only PDFs that do not require OCR, you can also append `--no-ocr` to avoid extra model paths and false recognition.)*",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2414,
  "completion_tokens": 607,
  "sec": 10.044779062271118,
  "cost": 0.00408675,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T02",
  "target": "mac_universal_clipboard",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "Yes. You can delete the Keychain item named:\n\n```text\nhandoff-own-encryption-key\n```\n\nDeleting this item resets your Mac's local Handoff encryption identity key without requiring a full iCloud sign-out.\n\n---\n\n### Step-by-Step Instructions\n\n1. **Open Keychain Access**:\n   * Press `Cmd + Space`, type **Keychain Access**, and press `Enter` (or open it from `/Applications/Utilities/Keychain Access.app`).\n2. **Search for the Key**:\n   * Select your **login** or **Local Items / iCloud** keychain, and type `handoff-own-encryption-key` into the search bar in the top-right corner.\n3. **Delete the Item**:\n   * Right-click (or Control-click) on `handoff-own-encryption-key` and select **Delete \"handoff-own-encryption-key\"**.\n   * Confirm the deletion when prompted.\n4. **Restart Continuity Daemons / Handoff**:\n   * Toggle Handoff off and back on in **System Settings > General > AirDrop & Handoff**.\n   * Alternatively, force-restart the services immediately by running this in Terminal:\n     ```bash\n     killall useractivityd 2>/dev/null; killall sharingd 2>/dev/null; killall pboard 2>/dev/null\n     ```\n   * Allow macOS a few moments to regenerate the key and re-establish the encrypted channel with your other devices, then test copy/paste between devices.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1010,
  "completion_tokens": 757,
  "sec": 12.20027494430542,
  "cost": 0.0035962499999999996,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T03",
  "target": "openreview",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "To resolve the HTTP 403 error caused by an expired authentication token, follow these steps:\n\n1. **Delete the cached token file:**\n   ```bash\n   rm tmp/openreview_token.json\n   ```\n\n2. **Retry your CLI query:**\n   Re-run your OpenReview command. The CLI will automatically re-authenticate using the credentials specified in your `.env` file (or `OPENREVIEW_EMAIL` / `OPENREVIEW_PASSWORD` environment variables), cache a fresh token, and execute the query.\n\n> **Note:** Only retry once, as OpenReview enforces a strict rate limit of at most 3 logins per time window.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1688,
  "completion_tokens": 391,
  "sec": 8.349972009658813,
  "cost": 0.0027322500000000003,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T04",
  "target": "workflow_bilibili_whisper_transcription",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "You should maintain a **2 to 3 second interval** between successive downloads (running single-threaded) to avoid triggering Bilibili's anti-scraping protections (such as 352 errors). \n\nIn addition, consider including appropriate `User-Agent` and `Referer` headers when downloading.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1655,
  "completion_tokens": 224,
  "sec": 7.611324787139893,
  "cost": 0.0020812499999999998,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T05",
  "target": "playwright_ajax_capture",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "This happens because many internal web APIs use asynchronous server-side processing: the `POST` request returns an async processing token (like `creation_uuid`) instead of the final resource ID, which is only generated once server processing finishes. Treating `creation_uuid` as the resource ID or expecting an immediate `id` field will pass `None` or an invalid identifier to subsequent calls.\n\nTo reliably obtain the real ID, use the **POST-then-GET with Content Matching** pattern:\n\n### Step-by-Step Procedure\n\n1. **Send the `POST` creation request**:\n   Submit your payload to create the resource as usual. Disregard any missing `id` or temporary `creation_uuid` in the response.\n\n2. **Send an immediate `GET` request to the list endpoint**:\n   Directly query the corresponding collection/list endpoint (e.g., `fetch_messages`, `list_posts`).\n\n3. **Locate the resource by content matching**:\n   Iterate over the returned items (usually sorted newest first) and match against the unique content or attributes you just submitted (e.g., specific text body, timestamp, or unique title).\n\n4. **Extract the real ID**:\n   Read the true resource ID (typically a numeric ID or canonical UUID) from the matched object in the list.\n\n5. **Proceed with dependent actions**:\n   Use this confirmed ID for subsequent calls (e.g., thread replies, updates, deletes).\n\n---\n\n### Implementation Example (Python `requests`)\n\n```python\nimport time\nimport requests\n\n# 1. POST the new item\npost_payload = {\"content\": \"Unique message text 1709123456\"}\nres_create = session.post(\n    \"https://target-domain.com/internal_api/items\", json=post_payload\n)\n\n# 2. Wait briefly if the backend processes asynchronously, then GET the list\ntime.sleep(1)\nres_list = session.get(\n    \"https://target-domain.com/internal_api/items?order=desc&limit=10\"\n)\nitems = res_list.json().get(\"items\", [])\n\n# 3 & 4. Match by content and extract the real ID\nreal_id = None\nfor item in items:\n    if item.get(\"content\") == post_payload[\"content\"]:\n        real_id = item[\"id\"]\n        break\n\nif not real_id:\n    raise RuntimeError(\"Failed to locate created item to retrieve real ID.\")\n\n# 5. Use the real ID for subsequent actions (e.g., thread reply)\nsession.post(\n    \"https://target-domain.com/internal_api/replies\",\n    json={\"parent_id\": real_id, \"content\": \"Reply to the confirmed item\"},\n)\n```",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 4541,
  "completion_tokens": 1183,
  "sec": 10.384925127029419,
  "cost": 0.007842,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": true
 },
 {
  "id": "T06",
  "target": "workflow_watchdog",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The recommended default inspection wake-up interval is **about 30 minutes (1800 seconds)**.\n\n### Recommended Steps:\n1. **Set the inspection wake-up immediately after dispatching:** Use `ScheduleWakeup` (in the Claude Code harness) or your environment's equivalent delayed execution/timing mechanism set for ~1800s. Do not wait in place.\n2. **Evaluate on wake-up:**\n   * **Genuinely busy:** If new output is appearing and the agent is making progress, leave it alone and set another wake-up interval or wait for completion.\n   * **Stuck in a loop:** If there is no progress or it is repeatedly retrying the same step, terminate the task (e.g., using `TaskStop` in Claude Code) and proceed using partial results or an alternative method.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 435,
  "completion_tokens": 364,
  "sec": 9.842446088790894,
  "cost": 0.00169125,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T07",
  "target": "workflow_parallel_subagents",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "You should not default to setting `temperature: 0` for subagents because:\n\n1. **Risk of repetition on long outputs**: Forcing absolute determinism on long text payloads can cause models to repeat phrases or get stuck in repetitive loops (for instance, while models like DS4 handle protocol structures deterministically, forcing fixed determinism on longer generations degrades output quality).\n2. **Provider-specific sampling strategies**: Many providers and models come tuned with their own optimized sampling strategies and default parameters. Overriding them globally can interfere with those optimizations.\n3. **Better default behavior**: You should leave temperature unset and allow the provider or server to use its built-in defaults, only specifying a fixed sampling configuration when you explicitly know a particular model requires it.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 3948,
  "completion_tokens": 392,
  "sec": 9.836675882339478,
  "cost": 0.004431,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T08",
  "target": "bestpractice_markdown_html_conversion",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "Based on the best practices for Markdown-to-HTML conversion and mobile adaptation, the recommended minimum padding is **24px or more**.\n\nTo implement this directly in your CSS, apply it to the `body` or your main container element:\n\n```css\nbody, \n.container {\n  padding: 24px;\n  box-sizing: border-box; /* Ensures padding is included in the element's total width */\n}\n```\n\nThis prevents text from clinging tightly to the display edges on mobile devices, providing a cleaner and more readable layout.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 709,
  "completion_tokens": 317,
  "sec": 9.793745756149292,
  "cost": 0.0017205000000000002,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T09",
  "target": "codex_cli",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "To disable `web_search` for your backend, configure it in your base config file (`$CODEX_HOME/config.toml`) or in the profile file loaded by your run.\n\n### 1. Value Type Required\nThe value **must be a string unit variant** with the exact value `\"disabled\"`.\n* **Accepted**: `\"disabled\"`\n* **Rejected**: Booleans like `false`, or strings like `\"off\"`, `\"on\"`, or `\"enabled\"` (these will fail with `expected string only in 'web_search'`).\n\n---\n\n### 2. Configuration Placement & Syntax\n\nAdd it as a **bare top-level key** placed **above all `[section]` headers** in your TOML configuration file (since TOML associates bare keys with any preceding table header).\n\n**Example (`config.toml`):**\n\n```toml\n# Must be at the very top, before any [section] headers\nweb_search = \"disabled\"\n\n[model]\n# other settings...\n```",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2084,
  "completion_tokens": 693,
  "sec": 11.327263116836548,
  "cost": 0.0041617500000000005,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T10",
  "target": "apple_photos",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The maximum number of image pairs allowed in a single delete manifest is **50 pairs**. \n\nLarger sets of evidence must be split into independent plans, each requiring its own fresh review and authorization.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2073,
  "completion_tokens": 133,
  "sec": 7.596817970275879,
  "cost": 0.0020535,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T11",
  "target": "colab",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "On Google Colab CLI version 0.7.4, an unrecognized `--gpu` value is not rejected—it is **sent as `A100`**.\n\nBecause the CLI defaults to requesting an A100 when it encounters an invalid accelerator name, you should always verify the actual assigned hardware after allocation (e.g., by querying `nvidia-smi --query-gpu=name,compute_cap,memory.total`) rather than relying on what was requested in the command flags.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 5586,
  "completion_tokens": 345,
  "sec": 5.265889644622803,
  "cost": 0.005483249999999999,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T12",
  "target": "dataforseo",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "### Cause of Error `40104`\n\nError code `40104` indicates that your credentials are valid and authenticated, but **your DataForSEO account has not completed verification**. \n\nBecause your credentials work, basic account endpoints like `balance` succeed. However, DataForSEO blocks access to keyword data endpoints—including the sandbox environment—until account verification is fulfilled.\n\n---\n\n### How to Fix It\n\n1. **Log into DataForSEO**:\n   Sign in to your account at the [DataForSEO Dashboard/Panel](https://app.dataforseo.com/).\n\n2. **Complete Account Verification**:\n   Navigate to your account profile/settings and finish any outstanding verification requirements (such as email confirmation, phone verification, or identity details requested by the platform).\n\n3. **Retry the Query**:\n   Once verified, run your CLI keyword command again:\n   ```bash\n   .venv/bin/dataforseo-skill keyword-suggestions \"agent harness\" --limit 5\n   ```",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 930,
  "completion_tokens": 523,
  "sec": 6.688223123550415,
  "cost": 0.0026587500000000005,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T13",
  "target": "firewalla",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "You need to include the **`--execute`** flag.\n\n### Why it is needed\n\nBy default, the `firewalla-skill` CLI runs in **dry-run mode** as a safety precaution to avoid unintended live network queries. Adding `--execute` explicitly confirms that you intend to query your physical Firewalla device.\n\n---\n\n### Example Usage\n\nTo collect live device and alarm data, include `--execute` in your commands:\n\n```bash\n# Check device connectivity/health\nfirewalla-skill health --execute\n\n# Collect all devices\nfirewalla-skill devices --execute --all --json --output reports/devices_all_latest.json\n\n# Collect alarms from the last 3 days\nfirewalla-skill alarms --execute --since-days 3 --include-archive --all --json --output reports/alarms_last3d_latest.json\n```\n\n*(Note: Remember to run these commands from `adhoc_jobs/firewalla_skill/` after activating your virtual environment with `source .venv/bin/activate`.)*",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1174,
  "completion_tokens": 546,
  "sec": 5.9779229164123535,
  "cost": 0.002928,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T14",
  "target": "apple_calendar",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "### Why `~/Library/Calendars` Failed\n\nOn modern macOS versions, `~/Library/Calendars/Calendar.sqlitedb` is a **0-byte decoy file**. If you copy or query this file directly, SQLite opens an empty database, causing queries to silently return zero rows.\n\n---\n\n### The Real Store Path\n\nThe actual live EventKit store is located in macOS's group container directory:\n\n```bash\n~/Library/Group Containers/group.com.apple.calendar/Calendar.sqlitedb\n```\n\n---\n\n### How to Copy and Query It Properly\n\nTo ensure you get valid, up-to-date data without hitting locks or stale data issues, follow these steps:\n\n1. **Copy the database and its WAL sidecar files:**\n   SQLite uses Write-Ahead Logging (`-wal`) and shared memory (`-shm`) sidecars where uncheckpointed writes reside. Copying only the `.sqlitedb` file can miss recent data or leave the database in an inconsistent state. Copy all three together:\n   - `Calendar.sqlitedb`\n   - `Calendar.sqlitedb-wal` (if present)\n   - `Calendar.sqlitedb-shm` (if present)\n\n   Example command to copy them to a temporary directory:\n   ```bash\n   mkdir -p /tmp/calendar_snapshot\n   cp ~/Library/Group\\ Containers/group.com.apple.calendar/Calendar.sqlitedb* /tmp/calendar_snapshot/\n   ```\n\n2. **Open in Read-Only Mode:**\n   Open the snapshot using SQLite in read-only mode so you do not accidentally alter it:\n   ```bash\n   sqlite3 \"file:/tmp/calendar_snapshot/Calendar.sqlitedb?mode=ro\"\n   ```\n\n---\n\n### Important Time Semantics Caveat\n\nWhen writing your queries against the snapshot, be aware of how EventKit stores timestamps:\n- Dates (`start_date`, `end_date`) are stored as **seconds since `2001-01-01 00:00:00 UTC`** (Apple's `NSDate` reference date), not standard Unix epochs (`1970-01-01`) and not local wall-clock times.\n- All-day events (`all_day = 1`) are pinned to UTC midnight (`00:00:00 UTC`) for that date, with their timezone set to floating (`_float`).",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2584,
  "completion_tokens": 868,
  "sec": 9.141713857650757,
  "cost": 0.005193,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T15",
  "target": "skill_image_generation",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "When creating infographics with GPT Image 2.5, use a **draft-and-repaint workflow** instead of generating from text alone.\n\n---\n\n### The Recommended Workflow\n\n1. **Generate a local structure draft first:**\n   * Create an initial chart or diagram locally using a tool like **matplotlib** to define the visual layout, chart blocks, titles, and data annotations.\n2. **Pass the draft as an input image to GPT Image 2.5:**\n   * Provide the draft file to the model using the `-i` flag to have GPT Image repaint and polish it:\n     ```bash\n     generate-image -p \"Redraw into a professional, polished infographic while preserving the layout and text annotations\" \\\n       -i draft_chart.png \\\n       -o output/infographic.png \\\n       --model gpt-image-2.5-sunburst \\\n       --aspect-ratio 16:9\n     ```\n3. **Set an extended timeout:**\n   * Complex chart redrawing routinely requires 300 seconds (5 minutes) or more. Ensure execution timeouts are raised accordingly (e.g., `timeout=300000`) so the process is not terminated prematurely.\n\n---\n\n### Why Use This Workflow?\n\n* **Unreliable from scratch:** Asking GPT Image 2.5 to generate an entire infographic purely from a text prompt produces unreliable structures, text positioning, and data organization.\n* **Layout and text preservation:** When fed a structure draft, the model acts as a \"repaint\" engine. It understands the underlying visual hierarchy, reliably preserves critical titles and annotations, and refines the styling and aesthetics.\n* **Deliverable compliance:** Raw local outputs (matplotlib, SVG, Mermaid, HTML/CSS screenshots) suffer from inconsistent rendering across different markdown viewers, mobile apps, and dark-mode themes. Redrawing the draft through a GPT Image model delivers a consistent, share-ready raster file (PNG, JPG, or WebP) suitable for final deliverables.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2057,
  "completion_tokens": 991,
  "sec": 10.692987203598022,
  "cost": 0.005259,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T16",
  "target": "skill_intake",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The sync step only reads and processes two audio file extensions:\n\n* **`.m4a`**\n* **`.qta`**\n\nAny other audio formats (such as `.wav` or `.mp3`) are ignored by the sync process. Additionally, note that `ffmpeg` is required to convert `.qta` files into normalized `.m4a` files during sync.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 4060,
  "completion_tokens": 348,
  "sec": 4.816147089004517,
  "cost": 0.00435,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T17",
  "target": "watch_development",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "To make the **Developer Mode** toggle appear on your Apple Watch, follow these steps:\n\n### 1. Ensure Prerequisites Are Met\nThe Apple Watch does not connect directly to your Mac over USB—its magnetic charging cable provides power only. It communicates exclusively through its paired iPhone.\n* Connect and trust your **paired iPhone** to the Mac (via USB cable or on the same Wi-Fi network).\n* Ensure **Bluetooth and Wi-Fi are turned on** for both your iPhone and Apple Watch.\n\n### 2. Pair the Watch to Your Mac in Device Hub\n1. On your Mac, open Xcode.\n2. Open **Device Hub** by navigating to **Xcode > Open Developer Tool > Device Hub** (or click the run-destination menu in Xcode and choose **Manage Devices…**).\n3. In Device Hub, click **\"+\" → \"Pair Nearby Device\"**.\n4. When prompted, a numeric pairing code will appear on the watch face; confirm the pairing code on the watch to establish trust.\n\n### 3. Restart the Apple Watch\n1. After pairing via Device Hub, perform a reboot on your Apple Watch (press and hold the side button, tap the power icon, slide to turn off, and then turn it back on).\n\n### 4. Enable Developer Mode\n1. After the watch reboots, open **Settings → Privacy & Security** on the watch. The **Developer Mode** option will now be visible.\n2. Tap **Developer Mode**, turn the toggle **ON**, and restart the watch once more when prompted by watchOS to finalize the change.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2827,
  "completion_tokens": 644,
  "sec": 9.347618103027344,
  "cost": 0.00453525,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T18",
  "target": "koyeb",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "You should not rely on the standard Koyeb CLI metrics command for zero-traffic verification because **the native CLI automatically maps upstream `null` values to `0`**. \n\nThis mapping obscures the distinction between:\n- **Actual zero traffic**: The service was active and legitimately received 0 requests.\n- **Null telemetry**: Data was missing, unreported, or uncollected during that time window.\n\nRelying on the standard CLI can lead to false positives—misinterpreting missing telemetry as genuine inactivity and prematurely triggering scale-to-zero actions.\n\n---\n\n### What to Use Instead\n\nUse the **lossless request metrics reader script**:\n```bash\npython3 scripts/request_metrics.py --service-id <service-id> \\\n  --start <UTC_START_TIME> --end <UTC_END_TIME> --step <STEP>\n```\n\n**Example:**\n```bash\npython3 scripts/request_metrics.py --service-id example-service-id \\\n  --start 2026-01-01T00:00:00Z --end 2026-01-01T01:00:00Z --step 1h\n```\n\n### Why `scripts/request_metrics.py` Solves This\n- **Preserves `null` vs. `0`**: Accurately reports raw nulls so your automation can verify true inactivity before scaling down.\n- **Preserves per-series labels**: Keeps detailed breakdown data intact.\n- **Telemetry safety**: It has an explicit narrow read-only exception in Koyeb operations to preserve raw telemetry safely without CLI-side data transformation.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2831,
  "completion_tokens": 827,
  "sec": 7.98787784576416,
  "cost": 0.0052245,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T19",
  "target": "narwal",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "In `narwal-local`, **`is_docked` and `charging_state` are always `null` by design** because raw status codes vary significantly across firmware versions and cannot be reliably normalized.\n\nTo determine whether the vacuum is docked and charging using the CLI, follow these steps:\n\n---\n\n### 1. Observe the Battery Trend (Primary Method)\nThe definitive way to verify that the robot is docked and charging is to check if the battery percentage is rising over time.\n\nYou can do this in one of two ways:\n\n#### Option A: Stream live telemetry with `watch`\nRun a bounded telemetry window to observe updates in real time:\n\n```bash\nnarwal-local watch --duration 60\n```\n- Examine the emitted JSONL lines and track `battery_percent`.\n- If the percentage climbs over the observation window, the robot is actively docked and charging.\n\n#### Option B: Compare two `snapshot` calls\nTake two snapshots spaced a couple of minutes apart:\n\n```bash\nnarwal-local snapshot\n# wait 2–3 minutes\nnarwal-local snapshot\n```\n- Check `data.base_query.battery_percent` in each output. An upward trend confirms the robot is charging at the dock.\n\n---\n\n### 2. Inspect the Raw Fields\nWhile `is_docked` and `charging_state` remain `null`, the CLI exposes the unparsed firmware values in:\n- `data.base_query.dock_raw`\n- `data.base_query.charging_status_raw`\n\nThese raw integers reflect the hardware status code reported by the robot's specific firmware.\n\n---\n\n### Summary Checklist\n* **Charging & Docked:** `battery_percent` increases over a `watch` window or between successive snapshots.\n* **Fully Charged at Dock:** `battery_percent` holds steady at `100.0` while `data.base_query.mode.semantic` reports `\"standby\"` and `task` fields remain null.\n* **Never assume `0` or absent means disconnected:** Always rely on dynamic trends rather than static boolean fields.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 4572,
  "completion_tokens": 892,
  "sec": 9.784533977508545,
  "cost": 0.006774,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T20",
  "target": "skill_opencode_data",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "### Why Subagent Fan-Out Sessions Are Missing\n\nBy default, the `export` command automatically skips subagent fan-out sessions. Additionally, `export` only generates markdown files for sessions that contain at least one user turn.\n\n### How to Include Them\n\nTo include subagent fan-out sessions in the export, add the **`--include-subagent`** flag to your export command.\n\n#### Example Command\n\nFrom your repository root:\n\n```bash\n.venv/bin/python -m opencode_skill export --out OUTPUT_DIR --include-subagent\n```\n\nYou can combine this with other flags such as `--since` (e.g., `--since 30d`) or `--dry-run` to preview the count before writing files:\n\n```bash\n.venv/bin/python -m opencode_skill export --out OUTPUT_DIR --include-subagent --since 30d --dry-run\n```\n\n*(Note: Exported markdown files contain private prompt and message bodies, so ensure they are not committed to source control.)*",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1489,
  "completion_tokens": 738,
  "sec": 6.077710151672363,
  "cost": 0.00388425,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T21",
  "target": "speaker_notes",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The strict upper limit (**hard gate**) is that **no ordinary spoken sentence may exceed 22 words**. \n\nAs a general guideline, ordinary sentences should be kept between **12 and 20 words** so they remain easy to deliver in a single breath.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 3118,
  "completion_tokens": 167,
  "sec": 2.3043971061706543,
  "cost": 0.0029647500000000004,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T22",
  "target": "skill_semantic_search",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "Based on the documentation for `semantic-search`:\n\n* **Command-line option:** Use **`--source-root`** (e.g., `--source-root /path/to/workspace`) to define the base directory that relative paths should resolve against.\n* **Default behavior if omitted:** The tool resolves relative entries against the **CLI's current working directory** (not the directory where the file list was generated).",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1859,
  "completion_tokens": 417,
  "sec": 4.639487981796265,
  "cost": 0.002958,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T23",
  "target": "smart_home_skill",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "**No**, you cannot retrieve the current volume level or mute status through the smart home integration's status endpoint.\n\n### Why:\n* **Protocol limitation:** Samsung TV control uses the local Tizen WebSocket API (`wss://<TV_IP>:8002`), which does not support reading volume or mute states back from the TV.\n* **Returned data:** The `get_status` endpoint only returns the TV's `PowerState`.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1130,
  "completion_tokens": 334,
  "sec": 4.530649185180664,
  "cost": 0.0021,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": true
 },
 {
  "id": "T24",
  "target": "skill_unifi",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "According to the documentation:\n\n* **Exit Code:** **`10`** indicates an authentication failure caused by an expired cookie.\n* **Resolution:** This is a manual human step. You must tell the human operator to refresh and export a new session cookie by following the instructions in `docs/cookie_refresh.md`.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 1026,
  "completion_tokens": 278,
  "sec": 3.9632272720336914,
  "cost": 0.001812,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T25",
  "target": "asr",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The maximum allowed duration for a single audio file is **7,200 seconds** (2 hours). \n\nAny single file exceeding 7,200 seconds is rejected before any model loads. \n\nIf your recordings are longer than this limit:\n- You must split them into separate files.\n- Note that splitting creates independent files, meaning speaker labels (letters) will not automatically continue across slices.\n- Multiple separate files that cumulatively exceed 7,200 seconds are permitted, provided no individual file exceeds the limit.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2197,
  "completion_tokens": 354,
  "sec": 5.13379693031311,
  "cost": 0.00297525,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T26",
  "target": "skill_outlook",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "The default timezone used by both `calendar invite` and `calendar update` is **UTC**.\n\nNote that on `calendar update`, it does not inherit the event's existing timezone. If you do not explicitly specify `--timezone`, the wall-clock times provided to `--start` and `--end` will be interpreted as UTC.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 3819,
  "completion_tokens": 297,
  "sec": 3.673977851867676,
  "cost": 0.003978,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": true
 },
 {
  "id": "T27",
  "target": "skill_resend_email",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "### Why this happened\n\nThe command failed because the `--after` flag is **not a timestamp or date filter**. Passing an ISO timestamp (like `2023-10-01T00:00:00Z`) causes the Resend API to return a validation error.\n\n### What `--after` actually expects\n\nIn Resend's API, `--after` and `--before` are **pagination cursors**. They expect **UUID cursor values** pointing to specific email records to page through results, rather than dates or times.\n\n---\n\n### How to filter by a time window\n\nTo analyze or retrieve messages from a specific date/time window, you should export recent messages locally and filter them by date using the file metadata:\n\n1. **Export a recent batch of messages to Markdown:**\n   ```bash\n   .venv/bin/python -m resend_email_skill.cli received export-all-md \\\n     --limit 100 \\\n     --output-dir data/received/markdown \\\n     --format json\n   ```\n\n2. **Filter locally:**\n   Inspect the YAML frontmatter in the exported `.md` files in `data/received/markdown/` and filter by the `created_at` timestamp.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2352,
  "completion_tokens": 510,
  "sec": 5.842482328414917,
  "cost": 0.0036765,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T28",
  "target": "skill_firecrawl",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "In the Firecrawl CLI, the `--include-domain` and `--exclude-domain` flags **cannot be used together** because they are mutually exclusive (an upstream Firecrawl API constraint).\n\nTo both target specific sites and exclude another site, use **`--include-domain`** for the allowed domains and the **`-site:` operator inside the query text** for the exclusion.\n\n### Example\n\nTo focus your search on `docs.anthropic.com` and `github.com`, while excluding `gist.github.com`:\n\n```bash\npython -m firecrawl_skill search \"agent framework -site:gist.github.com\" \\\n  --include-domain docs.anthropic.com \\\n  --include-domain github.com\n```\n\n### Steps to follow:\n1. Pass each domain you want to target using repeated `--include-domain <domain>` flags.\n2. In your query string, append `-site:<domain-to-exclude>`.\n3. Do **not** pass `--exclude-domain` when `--include-domain` is present (doing so triggers a CLI argument error).",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 6848,
  "completion_tokens": 645,
  "sec": 7.8804028034210205,
  "cost": 0.00755475,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T29",
  "target": "video-scoring-audio",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "You should avoid downmixing with `-ac 1` before measuring peak levels because of how ffmpeg handles correlated stereo signals (such as a mono voice-over or mix recorded onto both the left and right channels):\n\n1. **It artificially boosts the signal (+3 dB):** When downmixing correlated stereo channels to mono, ffmpeg sums the channels together, resulting in an approximate +3 dB gain boost.\n2. **It triggers false-positive clipping reports:** Because of this level boost, a mix that is actually safe and well below digital ceiling will appear to clip. For example, a mix with a true peak of -1.5 dBFS can measure at **1.19** after an `-ac 1` downmix, falsely reporting clipping that does not exist in the actual file.\n\n### What to do instead:\n* **Measure across all original channels** before downmixing (e.g., using `np.max(np.abs(xc))` across the shape `(-1, ch)`). Mono conversion should only be used for structural measurements like envelope tracking or spectral centroid calculations, never peak detection.\n* Use `ffmpeg -af ebur128=peak=true -f null -` as an independent cross-check for true peak and integrated loudness without altering channel levels.",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 5561,
  "completion_tokens": 667,
  "sec": 8.5898597240448,
  "cost": 0.006672,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 },
 {
  "id": "T30",
  "target": "skill_playwright_test",
  "model": "gemini-3.8-flash",
  "condition": "full_1",
  "answer": "This issue is caused by a **stale CDP Chrome profile / user-data-dir containing leftover session tokens from a previous test run**. \n\n### How it happens:\n1. The Chrome profile's `user-data-dir` retains expired or invalid session tokens from an earlier session.\n2. The SSO SDK detects the existing token on page load and attempts to authenticate with it.\n3. The backend rejects the stale token with a `401 Unauthorized`.\n4. The SSO SDK attempts to refresh the session or re-authenticate, sends another request, fails with another `401`, and repeats the cycle indefinitely between the \"loading\" and \"signing in\" states.\n\n---\n\n### How to fix it:\n* **For CDP manual/interactive sessions:** Clear the profile directory before launching Chrome:\n  ```bash\n  rm -rf /tmp/pw_debug_profile\n  ```\n  Always start Chrome with a fresh `--user-data-dir=/tmp/pw_debug_profile`.\n* **In automated Playwright test scripts:** Use an isolated context rather than reusing persistent storage:\n  ```python\n  context = await browser.new_context()\n  ```",
  "error": null,
  "n_skills": 1,
  "target_pos": 0,
  "prompt_tokens": 2337,
  "completion_tokens": 482,
  "sec": 5.982072114944458,
  "cost": 0.00356025,
  "web_tools": [],
  "n_calls": 1,
  "finish_reason": "stop",
  "nudged": false
 }
]