{"id":73084,"plugin_id":"plugin_asdk_app_6ac7e973de8481919c3e30951be3e9d9","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-31T01:17:50.627Z","digest":"5655c3de67d88777f6398b919fea7ce7c291e1d757981bb221e0982b8731b223","against":null,"payload":{"description":"Analyze app or collection feedback over a window — KPIs with prev-window deltas, rating/volume/ sentiment trends, anomaly callouts, and ranked top bugs + feature requests — then emit a structured findings.json plus a self-contained HTML report. Read-only (never writes). Trigger on \"feedback report\", \"how are our reviews\", \"what are users complaining about\", \"review trends for <app>\".\n","included_files":[{"relative_path":"references/method.md","size_in_bytes":1951},{"relative_path":"references/report-template.html","size_in_bytes":3366}],"name":"feedback-analysis","skill_md_contents":"---\nname: feedback-analysis\ndescription: >\n  Analyze app or collection feedback over a window — KPIs with prev-window deltas, rating/volume/\n  sentiment trends, anomaly callouts, and ranked top bugs + feature requests — then emit a structured\n  findings.json plus a self-contained HTML report. Read-only (never writes). Trigger on \"feedback\n  report\", \"how are our reviews\", \"what are users complaining about\", \"review trends for <app>\".\n---\n\n# feedback-analysis\n\nRead `using-appfollow` first. This skill is **read-only** — it never calls a write pair.\n\n## Inputs\n\n- **scope:** an app (`ext_id`+`store`), a whole collection, or a **user-chosen subset of apps from one\n  collection** (e.g. \"just these 3 apps from my <collection>\"). Spanning **multiple** collections in one\n  report is not supported yet (deferred).\n- **window:** default last 30 days; comparison = the preceding equal period.\n- **country / lang** (optional).\n- **depth:** `quick` | `standard` | `deep` = `get_reviews` page caps 2 / 5 / 10. **Default `deep`.**\n  `quick`/`standard` only on an explicit user request.\n\n## Two tiers, runtime-probed\n\nRead the advertised tool list; pick the plan (toolkit and MCP release trains are decoupled):\n\n- **Tier A (always):** `whoami`, `list_collections`, `list_apps`, `get_reviews`,\n  `get_ratings_history`.\n- **Tier B (degrade if the probe shows it absent):** `reviews_semantic`, `get_reviews_summary`,\n  `get_reviews_ai_summary`.\n- **Degradable, app-level (not a probe-gated tier):** `get_gp_console_ratings` — see Gather step B for\n  the degrade rule.\n\n## Gather (per app)\n\n0. **Session** (`using-appfollow`).\nA. **Scope resolve.** Collection lookup is **mandatory even for a bare ext_id** — `get_ratings_history`\n   and `get_reviews_ai_summary` require `collection_name` + `store`. For a subset scope: resolve the\n   collection via `list_collections`, list its apps via `list_apps`, then gather data for only the chosen\n   subset — emit `scope.type: \"collection_subset\"` with `collection_name` set and `apps` = the chosen\n   subset (not the full collection).\nB. **Cheap aggregates first.** One `get_ratings_history` spanning both windows (`period=daily`,\n   `type=total`, **explicit `limit`**); split client-side. `get_reviews_summary` × 2 windows (Tier B).\n   `get_gp_console_ratings` is degradable — the app may have no Google Play Console connection, or the\n   feature may be unavailable server-side. On any error (`VALIDATION_ERROR`, `UNKNOWN_TOOL`, or other),\n   or an empty response, omit the GP-console rating signal, note the gap in the report, and continue; the\n   App Store rating-history path is unaffected. Never fail the whole analysis on this call.\nC. **Narrative.** `get_reviews_ai_summary` (skip on `AUTH_REQUIRED`/`UPSTREAM_ERROR`/`NOT_FOUND`).\n   `reviews_semantic` — client-side classification is the first-class fallback. Then `get_reviews` raw\n   pages **per app** (`ext_id` — the tool does not accept a collection; loop the scope's apps) up to the\n   depth cap; stop early when `reviews.page.next` is null; replan after page-1 `total`; record coverage %.\n\n## Analyze\n\nFollow `references/method.md`: KPIs + deltas; daily-avg + 7-day-rolling trends; the anomaly heuristics\nwith their explicit thresholds; bug/feature mining (semantic-first, client-side classification the\ndefault fallback). Apply **coverage gating** — demote text-derived findings below the 60% floor to\n\"indicative only\". Ratings-derived findings are never coverage-gated. Group rollup weights by\n`rating_cnt` and merges cross-app clusters into `affected_apps`.\n\n## Error rails (`using-appfollow`)\n\n`INSUFFICIENT_CREDITS` → stop, emit a **partial** report + coverage note. `RATE_LIMITED` → one backoff\nthen continue. `NETWORK_ERROR`/`UPSTREAM_ERROR` on a non-critical call → skip that section, keep going.\nMissing Tier-B tool → documented fallback. Never fail the whole report on one tool error.\n\n## Emit\n\nWrite `./appfollow-reports/<report_id>/`:\n\n1. **`findings.json`** — `appfollow.toolkit.findings/v1`, `report_type:\"feedback\"`. Validate it against\n   `schemas/findings.schema.json` before writing. Each finding: stable `id`, `type`, `title`,\n   `description`, `severity`, `priority_hint`, `affected_apps`, `metrics`, `evidence` (3–5 quotes\n   ≤200 chars via review ids — no permalink scheme exists), `suggested_labels`, stable `dedup_key`\n   (so re-runs update rather than duplicate), `status:\"proposed\"`.\n2. **`report.html`** — fill `references/report-template.html`; inline SVG charts; no external requests.\n3. **`report.md`** — the same content in Markdown.\n\nOn Claude Code, also publish the HTML artifact; on Codex, write the files and state their path.\n\n## Findings hand-off\n\nTell the user their own connected tracker agent can file `findings.json` into their tracker — the\ntoolkit never talks to a tracker.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}