diff --git a/transformation-config/skills/cross-sell-3000/BUILD_NOTES.md b/transformation-config/skills/cross-sell-3000/BUILD_NOTES.md new file mode 100644 index 00000000..5b8b2e0f --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/BUILD_NOTES.md @@ -0,0 +1,68 @@ +# cross-sell-3000 — build notes + +Status as of **2026-06-08**. The growth-side sibling of `audit-3000` / `remediate-3000`. Share freely; update in-place as the skill evolves. + +## What this is + +`cross-sell-3000` grows a project's PostHog footprint **from the code outward**. It scans the repository to decide which PostHog products fit (unused products, competitors PostHog could replace, coverage gaps), then runs three connected jobs — **propose → plan → scaffold** — and writes working, build-verified code for the viable opportunities. It reads the code, not a CRM: every proposal cites `file:line` evidence. Modeled on `remediate-3000` (same plan-JSON ledger, baseline/verify discipline, parallel edit-group subagents, one-report output, no git mutations), but it *discovers* opportunities itself rather than consuming an audit report. + +| Step | File | Job | +|---|---|---| +| 1 | `1-detect.md` | Scan the codebase via 8 product detectors — all dispatched in one message as read-only `Explore`/`haiku` subagents, hard-capped at 4 Greps / 6 tool calls each (reuses audit-3000's detection map) → `/tmp/posthog-cross-sell-opportunities.json`. `[ABORT] No PostHog SDK found` when absent. | +| 2 | `2-baseline.md` | Detect package manager + verify command, record pre-scaffold baseline → `/tmp/posthog-cross-sell-env.json`. | +| 3 | `3-propose.md` | Drop healthy products; score fit/value/effort; classify `scaffold` vs `propose-only` → `/tmp/posthog-cross-sell-plan.json`. | +| 4 | `4-plan.md` | Write a `plan` block (files/approach/snippet) for each scaffold item — **a single illustrative example, one file** (not full coverage). One subagent per item, all in one message, on `model: "sonnet"`. Orchestrator passes the evidence `file:line` list from the plan and **never pre-reads the files itself** (subagents read). | +| 5 | `5-scaffold.md` | Apply the one-example-per-product scaffolds via parallel `sonnet` subagents (one per edit group); install added PostHog packages once. Subagents apply exactly the one-file plan, never extend to other sites. | +| 6 | `6-verify.md` | Spot-check each scaffold + re-run baseline command; one repair pass; revert on unfixable regression. | +| 7 | `7-report.md` | Render a **short** `posthog-cross-sell-report.md` (overview table + one line per item; no code blocks); delete `/tmp/` intermediates. Per-item sub-sections fan out to one `Explore`/`haiku` subagent each (formatting, not judgment), then the orchestrator writes the aggregate sections and collapses them in. Terminal. | + +## Design decisions worth knowing + +1. **Code-grounded, not sales-data-driven.** By explicit product direction, the skill never consults a CRM or external enrichment — fit is judged purely from repository evidence (`file:line`). This is the key difference from audit-3000's Step 7/8 enrichment + playbook machinery, which this skill deliberately omits. +2. **Detection map reused from audit-3000.** Step 1's per-product grep patterns, competitor packages, and env-var names are lifted from `audit-3000/references/9-use-case-expansion.md` so the two skills classify products identically. If that map changes, mirror it here. + - **Detectors are cheap, wide, and capped.** All eight run in a single message (no serial batches) as `subagent_type: "Explore"` / `model: "haiku"`, each hard-capped at one Grep per detector (4 total) and 6 tool calls. Detection is grep-and-classify, so a heavier model is wasted there and the cap stops detectors from wandering (an early run saw 7–18 tool calls each across two serial batches). The judgment-heavy steps (plan/scaffold) pin `model: "sonnet"` — never opus. Step 6's read-only spot-checks fan out the same way when there are several items. +3. **Three jobs, three steps.** propose (Step 3: which + why + scaffold/propose-only), plan (Step 4: the implementation detail per scaffold item), scaffold (Step 5: apply). Kept separate because the user asked for all three as distinct deliverables and each is independently verifiable. +4. **Scaffold vs propose-only is conservative.** Only code-driven integrations with a concrete surface and (at most) an official-PostHog-package dependency get scaffolded. Surveys (UI-configured), Logs (backend choice), and any greenfield product with no surface stay proposal+plan. The report still hands the operator a full plan for those. +5. **Scaffolds are minimal and reversible.** Feature-gated, single-provider, comment-marked (`// PostHog — scaffolded by cross-sell`), defaulting to current behavior. No demo routes, no placeholder flags wired to nothing. +6. **PostHog-only dependencies.** Subagents may add an official PostHog package to the manifest (orchestrator installs once); they may never add a non-PostHog dependency or `npm install` themselves. +7. **Baseline before, verify after, one repair pass, then revert** — identical safety contract to remediate-3000, so a scaffold that breaks the build is backed out rather than left half-applied. +8. **Operator commits.** Git state is recorded, never mutated. Each scaffolded product carries a **Finish in PostHog** step (create the flag, build the survey) because code alone doesn't activate most products. +9. **Task pane + wizard summary.** description.md uses `TaskCreate`/`TaskUpdate` (so the wizard task pane populates) and Step 7 permits the wizard-owned `posthog-cross-sell-3000-report.md` summary — same conventions as the current remediate-3000. +10. **Read-only work fans out; map-reduce the report.** Every read-only phase is parallelized — Step 1 detect, Step 4 plan, Step 6 spot-checks, and Step 7's per-item report sub-sections all dispatch one subagent per unit of work in a single message. Cheap (`Explore`/`haiku`) for the formatting/grep-and-classify work (detect, verify, report sections); `sonnet` for the judgment work (plan, scaffold). **Never opus — nothing in this skill runs above sonnet.** Step 5 scaffold stays grouped-by-shared-file because it *writes* (conflict avoidance), not because it can't parallelize. The aggregate report sections (Summary, Opportunity overview, Next steps) are written by the orchestrator after the fan-out collapses, since each needs the whole result set. Step 4's orchestrator must NOT pre-read evidence files — an early run wasted ~1m35s doing ~22 serial `Read`/`Grep` before dispatching planners that re-read the same files; it now passes the evidence paths straight to the subagents. +11. **One example per product, short report (demo cap).** Step 4 plans and Step 5 applies a *single illustrative example* per viable product — one file, one minimal change — not full coverage; the report tells the operator to replicate at the other sites. The report is deliberately terse (table + one line per item, no code blocks). This keeps a demo run fast and the diff small. To restore full-coverage scaffolding, drop the "single representative example / exactly one entry in `files`" wording in `4-plan.md` and the one-line-per-item constraint in `7-report.md`. + +## Running it + +### Build the skill + +From `context-mill/` — set `SKILLS_BASE_URL` so `--local-mcp` downloads resolve to the dev server (a bare `node scripts/build.js` points downloadUrls at GitHub releases and unpublished skills 404): + +```bash +SKILLS_BASE_URL=http://localhost:8765/skills node scripts/build.js # one-shot +node scripts/dev-server.js # watch mode on :8765 (sets the env var itself) +``` + +### Run via the wizard + +```bash +cd +wizard --local-mcp --skill="cross-sell-3000" +``` + +The wizard's generic `agent-skill` program runs any context-mill skill by id — no wizard code changes needed. No prior audit-3000 run is required; the skill detects opportunities itself. + +### Smoke test without the wizard + +```bash +cd +mkdir -p .claude/skills/cross-sell-3000 +unzip -o /dist/skills/cross-sell-3000.zip -d .claude/skills/cross-sell-3000 +# Then in Claude Code: "Run the cross-sell-3000 skill from +# .claude/skills/cross-sell-3000/SKILL.md. Walk every step in order." +``` + +## Open issues / known TODOs + +1. **Interactive selection.** Step 3 auto-classifies scaffold vs propose-only. A future wizard version could surface the proposal in the TUI and let the operator pick which products to scaffold before Step 5 runs. +2. **Flag/survey creation via MCP.** When the session has a PostHog MCP with write scopes, the **Finish in PostHog** steps (create the flag, build the survey) could become opt-in actions instead of manual instructions. +3. **Pairing with audit-3000.** A natural three-skill story: audit-3000 (find problems) → remediate-3000 (fix them) → cross-sell-3000 (grow adoption). Worth cross-linking in each skill's report Next steps. diff --git a/transformation-config/skills/cross-sell-3000/config.yaml b/transformation-config/skills/cross-sell-3000/config.yaml new file mode 100644 index 00000000..95097963 --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/config.yaml @@ -0,0 +1,17 @@ +type: docs-only +template: description.md +description: Detect which PostHog products fit a codebase, propose them, plan the work, and scaffold the viable ones (v3000) +tags: [best-practices] +references: + preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." +# Only docs with distinct URL basenames can be bundled — the build derives the +# filename from the last path segment, so several `.../installation.md` URLs +# would collide. Per-product installation docs are referenced by full URL in +# references/4-plan.md instead. +shared_docs: + - https://posthog.com/docs/product-analytics/best-practices.md +variants: + - id: all + display_name: PostHog cross-sell 3000 + tags: [best-practices] + docs_urls: [] diff --git a/transformation-config/skills/cross-sell-3000/description.md b/transformation-config/skills/cross-sell-3000/description.md new file mode 100644 index 00000000..209f1116 --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/description.md @@ -0,0 +1,74 @@ +# PostHog Cross-Sell 3000 + +This skill grows a project's PostHog footprint **from the code outward**. It scans the codebase to see which PostHog products would fit — products the team isn't using yet, competitor tools PostHog could replace, and surfaces where an in-use product is missing coverage — then **proposes** the strongest opportunities, **plans** the implementation for each, and **scaffolds** working code for the ones that are viable today. It reads the code, not a CRM: every proposal is grounded in `file:line` evidence from the repository, never external sales data. + +The flow is three connected jobs: **propose** (which products fit and why) → **plan** (the concrete implementation for each viable one) → **scaffold** (apply a minimal, build-verified integration). Opportunities that need a product decision or a missing dependency before code can land (e.g. a brand-new logging backend, surveys that are configured in the PostHog UI) are kept as **proposal + plan only**, not scaffolded. + +**Write contract.** This skill edits project source — scaffolding is its job — but it only edits files named by a plan item (or files the item's plan explicitly describes), it never runs `git commit`, `git push`, or any other git mutation, it never mutates PostHog state through MCP, and the only new dependencies it may add are official PostHog packages. It creates exactly **one** new file at the project root: `posthog-cross-sell-report.md`. Intermediate state lives in `/tmp/` while the chain runs (`/tmp/posthog-cross-sell-opportunities.json`, `/tmp/posthog-cross-sell-plan.json`, `/tmp/posthog-cross-sell-env.json`) and the final step deletes all three. The operator reviews the diff and commits — not this skill. + +## Workflow + +The cross-sell run is a step chain. **The exact step list lives in the reference files themselves, not in this overview.** Step 1 lives at `references/1-detect.md`; each step file ends with a `next_step:` frontmatter pointer to the next, and the final step has `next_step: null`. Follow them in the order they point. You must resolve each step in order. + +**Start by reading the path relative to this file at `references/1-detect.md`.** Do not Glob, ls, or find the skill directory. Do not preload future steps. Do not re-read a step file once you've moved past it. Do not re-read SKILL.md. + +`ToolSearch` is only for loading a tool by exact name when the SDK has it deferred (e.g. `select:Grep`). Do **not** use it to browse for other tools — every tool the run needs (`Glob`, `Grep`, `Read`, `Edit`, `Write`, `Bash`, `Agent`, `TaskCreate`, `TaskUpdate`) is already named in this skill. + +## State files + +Two `/tmp/` files carry state across steps; read them, patch them, and write them back in full when a step says so: + +- `/tmp/posthog-cross-sell-opportunities.json` — created by Step 1. The raw per-product detection result. +- `/tmp/posthog-cross-sell-plan.json` — created by Step 3, the single source of truth for what gets proposed/scaffolded thereafter. Each item carries: + - `id` — stable kebab-case slug (`feature-flags`, `error-tracking`, …). + - `product` — PostHog product name. + - `mode` — `cross-sell` | `greenfield` | `gap` (in-use-and-healthy products are dropped, not carried). + - `competitor` — competitor name when `mode` is `cross-sell`, else `null`. + - `fit` — `high` | `medium` | `low`. + - `value` — one or two sentences on the business/analytics upside. + - `effort` — `S` | `M` | `L`. + - `evidence` — `file:line` list backing the fit. + - `classification` — `scaffold` | `propose-only`. + - `skip_reason` — required when `propose-only`. + - `plan` — `{ files, approach, snippet }`, added in Step 4 for `scaffold` items. + - `status` — `proposed` | `planned` | `scaffolded` | `verified` | `failed` | `propose-only`. + - `notes` — one-line record of what was scaffolded or why it failed. + +## Severity / priority ordering + +Whenever a step processes items, order them by `fit` (high → medium → low), then by `effort` (S → M → L). The highest-leverage, lowest-cost opportunities land first, so a partial run still delivers the best ones. + +## Key principles + +- **Code-grounded**: every proposal cites concrete `file:line` evidence. No opportunity without evidence. +- **Plan-driven scaffolding**: every edit traces to a plan item's `plan` block. No freelance code. +- **Minimal, idiomatic diffs**: scaffolds are the smallest working integration, matching the file's existing style. Prefer a feature-gated or clearly-marked addition over sweeping changes. +- **Fail safe**: if a scaffold can't be applied cleanly, mark the item `failed` with a reason instead of guessing. A failed item with a clear note beats a wrong edit. +- **Verify before reporting**: scaffolds are spot-checked mechanically and the project's own typecheck/lint/build is re-run against a baseline recorded before any edit. + +## Task list + +As soon as you have a rough sense of the work, **call `TaskCreate` immediately** — before reading the first reference file — so the task pane isn't empty. Seed it with the high-level phases you can infer (detect, propose, plan, scaffold, verify, report), then refine with `TaskCreate`/`TaskUpdate` as your understanding sharpens. Mark an item `in_progress` when you start it and `completed` when you finish. Keep titles broad and job-oriented ("Detecting product fit", "Scaffolding viable products"), not file-specific. + +## Status + +Before beginning each phase or sub-step, emit a plain-text line with the exact prefix `[STATUS]`: + +``` +[STATUS] Detecting product fit +``` + +The harness intercepts these and updates the "Working on …" banner. Use them freely — each step file lists the exact strings to emit. + +## Abort statuses + +Report abort states with `[ABORT]` prefixed messages. The wizard catches these and terminates the run — do not halt yourself. +- No PostHog SDK found + +## Reference files + +{references} + +## Framework guidelines + +{commandments} diff --git a/transformation-config/skills/cross-sell-3000/references/1-detect.md b/transformation-config/skills/cross-sell-3000/references/1-detect.md new file mode 100644 index 00000000..8cbd172b --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/1-detect.md @@ -0,0 +1,164 @@ +--- +next_step: 2-baseline.md +--- + +# Step 1: Detect which PostHog products fit the codebase + +This step scans the repository, classifies each PostHog product into a cross-sell mode, and writes the raw result to `/tmp/posthog-cross-sell-opportunities.json`. It does NOT rank, value, or classify-for-scaffolding (Step 3 owns that), does NOT plan implementations (Step 4), and does NOT edit any source file. Detection is read-only. + +## Status + +Emit: + +``` +[STATUS] Locating PostHog SDK +[STATUS] Detecting product fit +``` + +## Action + +### a. Clear any stale intermediates + +This skill's `/tmp` files are owned by the *current* run. An interrupted earlier run can leave them behind (Step 7 cleanup only runs on success), and reusing them makes Steps 3–4 short-circuit on stale data instead of replanning. Before anything else, wipe them in one `Bash` call: + +``` +rm -f /tmp/posthog-cross-sell-opportunities.json /tmp/posthog-cross-sell-plan.json /tmp/posthog-cross-sell-env.json +``` + +### b. Confirm PostHog is installed + +`Glob` the dependency manifests (`package.json`, `requirements.txt`, `pyproject.toml`, `Gemfile`, `composer.json`, `go.mod`, `*.csproj`, `pubspec.yaml`, …) and confirm at least one PostHog SDK is declared. Record the SDKs and the project's primary language/framework. If no PostHog SDK exists anywhere, emit `[ABORT] No PostHog SDK found` and stop. + +### c. Run all eight product detectors at once + +Dispatch **all eight `Agent` subagents in a single message** — one per PostHog product, no batching. They are shallow read-only classifiers, so run each with `subagent_type: "Explore"` and `model: "haiku"` to keep them fast and cheap. The harness queues them under its own concurrency cap — you do not manage batches or wait between them. Run no other tool between dispatch and collection. + +One subagent per product: `product-analytics`, `error-tracking`, `llm-observability`, `session-replay`, `feature-flags`, `surveys`, `logs`, `web-analytics`. + +Each subagent's `description`: `Detect fit`. Each subagent's `prompt`, with `<>` filled from the **Detection map** below: + +``` +You are a cross-sell detection subagent. Assess the project's fit for PostHog and return one JSON object. Read-only — do not edit any file. + +## Budget — stay fast (hard cap) +This is a shallow classification, not an investigation. Run **at most one Grep per detector below (four Grep calls total)**, never `Read` a whole file — classify from the Grep hit lines alone — and return your JSON within **six tool calls**. The moment you can pick a mode, stop searching and return. Going wider does not improve the answer. + +## Detector A — is PostHog already in use? +Run one Grep for: +Also check the dependency manifest for: +In use if any pattern matches OR the package is declared. + +## Detector B — is a competitor in use? +Run one Grep for: +Check the manifest for competitor packages: +Check .env* files for competitor env var NAMES only (never read or log values): +If any match, record the first competitor's name. + +## Detector C — fit evidence +Grep for the code surfaces that signal this product would add value: +Collect up to 5 file:line hits as evidence. + +## Classify mode +- PostHog in use + missing coverage on a surface Detector C found → mode "gap" +- PostHog in use + no obvious gap → mode "in-use" (healthy) +- PostHog NOT in use + competitor detected → mode "cross-sell" +- PostHog NOT in use + no competitor → mode "greenfield" + +Stay conservative: only cite concrete file:line evidence, never speculation. + +Return exactly this JSON (no prose): +{ + "id": "", + "product": "", + "mode": "cross-sell|greenfield|gap|in-use", + "posthog_present": true|false, + "competitor": ""|null, + "competitor_evidence": ["file:line or package", ...], + "fit_evidence": ["file:line", ...] +} +``` + +### d. Aggregate + +Collect the eight JSON objects. `Write` `/tmp/posthog-cross-sell-opportunities.json`: + +```json +{ + "project_root": "", + "language": "", + "sdks": { "posthog-js": "", "posthog-node": "..." }, + "products": [ ] +} +``` + +## Detection map + +Per-product values for the subagent prompt. Patterns are regex for `Grep`. + +**`product-analytics` — Product Analytics** +- PostHog presence: `posthog\.capture\(|@posthog/(?:react|node|nextjs|js|web)|posthog-js|posthog-node|posthog-python|posthog-ruby|posthog-go` +- PostHog packages: `posthog-js`, `posthog-node`, `posthog-python`, `posthog-ruby`, `posthog-go`, `@posthog/ai` +- Competitor patterns: `mixpanel\.(?:track|init|identify)|amplitude\.(?:track|init)|@amplitude/|heap\.track|gtag\(|@analytics/` +- Competitor packages: `mixpanel-browser`, `mixpanel`, `@amplitude/analytics-browser`, `amplitude-js`, `heap-analytics` +- Competitor env vars: `MIXPANEL_TOKEN`, `AMPLITUDE_API_KEY`, `HEAP_ENV_ID` +- Fit signals: route/page components and key user actions (button onClick handlers, form submits, checkout/purchase paths) with no nearby `posthog.capture`. + +**`error-tracking` — Error Tracking** +- PostHog presence: `captureException|\$exception|posthog\.captureException` +- PostHog packages: `posthog-js`, `posthog-node` (errors are core SDK) +- Competitor patterns: `Sentry\.(?:init|captureException)|@sentry/|Bugsnag\.|@bugsnag/|Rollbar\.|rollbar|Honeybadger\.` +- Competitor packages: `@sentry/browser`, `@sentry/node`, `@sentry/react`, `@sentry/nextjs`, `sentry-sdk`, `@bugsnag/js`, `rollbar`, `honeybadger-js` +- Competitor env vars: `SENTRY_DSN`, `NEXT_PUBLIC_SENTRY_DSN`, `BUGSNAG_API_KEY`, `ROLLBAR_ACCESS_TOKEN` +- Fit signals: `catch\s*\(` blocks that swallow errors (empty, or only `console.error`/`console.log`) and are not reporting to any tracker. + +**`llm-observability` — LLM Observability** +- PostHog presence: `\$ai_generation|@posthog/ai|posthog-ai|withTracing\(` +- PostHog packages: `@posthog/ai` +- Competitor patterns: `langfuse|@langfuse/|Helicone|@helicone/|LangSmith|langsmith|braintrust|@arizeai/` +- Competitor packages: `langfuse`, `helicone`, `langsmith`, `braintrust`, `@arizeai/phoenix-client` +- Competitor env vars: `LANGFUSE_PUBLIC_KEY`, `HELICONE_API_KEY`, `LANGSMITH_API_KEY`, `BRAINTRUST_API_KEY` +- Fit signals: LLM call sites — `openai\.|@ai-sdk|generateText|streamText|Anthropic|@anthropic-ai|langchain|bedrock` — not wrapped in any tracing. + +**`session-replay` — Session Replay** +- PostHog presence: `session_recording|disable_session_recording|startSessionRecording|getSessionReplayUrl` +- PostHog packages: `posthog-js` +- Competitor patterns: `LogRocket\.|@logrocket/|FS\.(?:init|identify)|@fullstory/|window\.hj|Hotjar\.|clarity\(` +- Competitor packages: `logrocket`, `@fullstory/browser`, `react-hotjar`, `@hotjar/browser`, `@microsoft/clarity` +- Competitor env vars: `LOGROCKET_APP_ID`, `FULLSTORY_ORG_ID`, `HOTJAR_ID`, `CLARITY_PROJECT_ID` +- Fit signals: a web client SDK (`posthog-js`) present but `disable_session_recording: true`, or no replay config in init. + +**`feature-flags` — Feature Flags** +- PostHog presence: `getFeatureFlag\(|isFeatureEnabled\(|useFeatureFlag|getFeatureFlagPayload|onFeatureFlags` +- PostHog packages: `posthog-js`, `posthog-node` (flags are core SDK) +- Competitor patterns: `LDClient\.|@launchdarkly/|launchdarkly-|splitio|@splitsoftware/|statsig|@statsig/|@optimizely/|flagsmith|growthbook` +- Competitor packages: `launchdarkly-js-client-sdk`, `launchdarkly-node-server-sdk`, `@splitsoftware/splitio`, `statsig-js`, `statsig-node`, `@optimizely/react-sdk`, `flagsmith`, `growthbook` +- Competitor env vars: `LAUNCHDARKLY_SDK_KEY`, `LD_SDK_KEY`, `SPLIT_API_KEY`, `STATSIG_SERVER_KEY`, `OPTIMIZELY_SDK_KEY`, `FLAGSMITH_ENVIRONMENT_ID` +- Fit signals: hardcoded toggles that want to be flags — `process.env.*(?:FLAG|ENABLE|BETA)|if \(process\.env\.NODE_ENV`, beta/experimental conditional blocks, commented-out features. + +**`surveys` — Surveys** +- PostHog presence: `getActiveMatchingSurveys|renderSurvey|posthog\.getSurveys` +- PostHog packages: `posthog-js` +- Competitor patterns: `Typeform|@typeform/|SurveyMonkey|sprig\.|@sprig-technologies/|wootric|qualaroo|delighted` +- Competitor packages: `@typeform/embed`, `react-typeform-embed`, `@sprig-technologies/sprig-browser`, `wootric`, `delighted` +- Competitor env vars: `TYPEFORM_API_TOKEN`, `SPRIG_ENVIRONMENT_ID`, `WOOTRIC_ACCOUNT_TOKEN` +- Fit signals: feedback / NPS / contact / onboarding surfaces — files matching `feedback|nps|contact|onboard|review|cancel` — that collect sentiment via custom forms. + +**`logs` — Logs** +- PostHog presence: `@posthog/otel|@posthog/logs|posthog\.captureLog` +- PostHog packages: `@posthog/otel`, `@posthog/logs` +- Competitor patterns: `@datadog/browser-logs|dd-trace|@sumologic/|@logtail/|betterstack|@logzio/|loggly|pino-loki` +- Competitor packages: `@datadog/browser-logs`, `dd-trace`, `@logtail/node`, `@logtail/browser`, `winston`, `pino`, `bunyan` +- Competitor env vars: `DATADOG_API_KEY`, `DD_API_KEY`, `LOGTAIL_SOURCE_TOKEN`, `BETTER_STACK_SOURCE_TOKEN` +- Fit signals: server/API directories with ad-hoc `console\.(error|warn|log)` or a logger (`winston`/`pino`) and no structured log sink. + +**`web-analytics` — Web Analytics** +- PostHog presence: `\$pageview|\$pageleave|capture_pageview|capture_pageleave` +- PostHog packages: `posthog-js` +- Competitor patterns: `gtag\(|google-analytics|GoogleAnalytics|plausible|fathom|matomo|window\._paq` +- Competitor packages: `react-ga4`, `react-ga`, `plausible-tracker`, `fathom-client`, `matomo-tracker` +- Competitor env vars: `NEXT_PUBLIC_GA_ID`, `GA_TRACKING_ID`, `PLAUSIBLE_DOMAIN`, `FATHOM_SITE_ID`, `MATOMO_URL` +- Fit signals: `posthog-js` present but pageview/pageleave not enabled (no `capture_pageview`, `defaults`, or `$pageview` capture). + +## Output + +`/tmp/posthog-cross-sell-opportunities.json` exists with all eight product objects. diff --git a/transformation-config/skills/cross-sell-3000/references/2-baseline.md b/transformation-config/skills/cross-sell-3000/references/2-baseline.md new file mode 100644 index 00000000..5a26e4bc --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/2-baseline.md @@ -0,0 +1,58 @@ +--- +next_step: 3-propose.md +--- + +# Step 2: Record the project toolchain and baseline + +The detection result is at `/tmp/posthog-cross-sell-opportunities.json` (Step 1). This step detects the project's package manager and verification command, runs that command once to record a pre-scaffold baseline, and writes `/tmp/posthog-cross-sell-env.json`. It does NOT propose, plan, or edit anything. Later steps need this so Step 6 can tell a scaffold-induced regression apart from a pre-existing failure. + +## Status + +Emit: + +``` +[STATUS] Detecting toolchain +[STATUS] Recording baseline +``` + +## Action + +### a. Detect the package manager and commands + +From `project_root`, identify the package manager by lockfile: `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `bun.lockb`/`bun.lock` → bun, `package-lock.json` → npm. For non-JS projects use the manifest's ecosystem (pip/uv, bundler, composer, go, …). + +Pick **one** verification command, in preference order: + +1. A `typecheck` script in the manifest, else `tsc --noEmit` when `tsconfig.json` exists. +2. A `lint` script. +3. A `build` script. +4. None → record `verify_cmd: null`. + +Record the matching `install_cmd` (`pnpm install`, `npm install`, …) so a scaffold that adds a PostHog package can install it. + +### b. Record git state + +Run `git rev-parse --is-inside-work-tree` and, if a repo, `git status --porcelain`. Record whether the tree is dirty. **Record only** — do not commit, stash, branch, or otherwise mutate git state, and do not abort on a dirty tree. + +### c. Run the baseline + +If `verify_cmd` is set, run it once from `project_root`. Record whether it passed and, on failure, a one-line summary of the error count and files involved. Do not fix any baseline failure. + +### d. Write the env file + +`Write` `/tmp/posthog-cross-sell-env.json`: + +```json +{ + "package_manager": "pnpm", + "install_cmd": "pnpm install", + "verify_cmd": "pnpm typecheck", + "baseline_pass": true, + "baseline_summary": null, + "git": { "repo": true, "dirty": false } +} +``` + +## Output + +The env file exists with all six keys populated (nulls allowed where detection found nothing). diff --git a/transformation-config/skills/cross-sell-3000/references/3-propose.md b/transformation-config/skills/cross-sell-3000/references/3-propose.md new file mode 100644 index 00000000..d47f0be6 --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/3-propose.md @@ -0,0 +1,69 @@ +--- +next_step: 4-plan.md +--- + +# Step 3: Turn detections into a prioritized proposal + +The detection result is at `/tmp/posthog-cross-sell-opportunities.json` (Step 1); the toolchain is at `/tmp/posthog-cross-sell-env.json` (Step 2). This step drops healthy products, scores the rest for fit/value/effort, decides which are scaffoldable today, and writes `/tmp/posthog-cross-sell-plan.json`. It does NOT write per-item implementation plans (Step 4 owns the `plan` block) and does NOT edit source. + +## Status + +Emit: + +``` +[STATUS] Prioritizing opportunities +[STATUS] Writing the proposal +``` + +## Action + +### a. Drop non-opportunities + +Read the opportunities file. Discard every product whose `mode` is `in-use` (already adopted and healthy — nothing to sell). Keep `cross-sell`, `greenfield`, and `gap`. + +### b. Score each kept product + +For each, decide: + +- `fit` — `high` when the evidence is strong and concrete (a competitor in active use, or a clear uninstrumented surface); `medium` when evidence is partial; `low` when the signal is weak or speculative. +- `value` — one or two sentences naming the specific upside for *this* project, referencing what the evidence shows (e.g. "Three catch blocks in the API routes swallow errors silently — Error Tracking would surface them with stack traces and session context"). Tie cross-sell modes to the consolidation win ("replace Sentry, unify with the analytics you already send"). +- `effort` — `S` (a few call-sites, SDK already present), `M` (new init/provider wiring or a new PostHog package), `L` (spans many surfaces or needs product/config decisions). + +### c. Classify scaffold vs propose-only + +- `scaffold` — the integration is code-driven, the only new dependency (if any) is an official PostHog package, and Step 1 found a concrete surface to wire it into. Typical: Feature Flags (gate a real existing toggle), Error Tracking (wire `captureException` into existing catch blocks), Product Analytics / Web Analytics gaps (add captures on a named surface), LLM Observability (wrap an existing AI client), Session Replay (enable in init). +- `propose-only` — needs a decision or setup code can't safely make on its own: a product configured outside code (Surveys are built in the PostHog UI), a new backend/infra choice (Logs sink selection), or a greenfield product with no concrete surface in the repo yet. Record a one-line `skip_reason`. + +Anything with `fit: low` is `propose-only` regardless, unless the fix is a trivial one-line init change. + +### d. Write the plan + +`Write` `/tmp/posthog-cross-sell-plan.json`, items ordered by `fit` (high→low) then `effort` (S→L): + +```json +{ + "project_root": "", + "items": [ + { + "id": "feature-flags", "product": "Feature Flags", + "mode": "greenfield", "competitor": null, + "fit": "high", "value": "...", "effort": "S", + "evidence": ["app/rate/page.tsx:31"], + "classification": "scaffold", "skip_reason": null, + "plan": null, + "status": "scaffold" ? "proposed" : "propose-only", + "notes": null + } + ] +} +``` + +Set `status` to `proposed` for `scaffold` items and `propose-only` for the rest. + +## Output + +The plan file exists; its item count equals the kept-product count (everything except `in-use`). Finish by emitting: + +``` +[STATUS] Proposal ready: to scaffold, proposal-only +``` diff --git a/transformation-config/skills/cross-sell-3000/references/4-plan.md b/transformation-config/skills/cross-sell-3000/references/4-plan.md new file mode 100644 index 00000000..9e1953a3 --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/4-plan.md @@ -0,0 +1,76 @@ +--- +next_step: 5-scaffold.md +--- + +# Step 4: Write an implementation plan for each scaffold item + +The plan is at `/tmp/posthog-cross-sell-plan.json` (Step 3). This step fills the `plan` block for every `proposed` (scaffold-bound) item — the concrete files, approach, and a code snippet — so Step 5 can apply it mechanically. It does NOT edit project source and does NOT touch `propose-only` items beyond leaving them as-is. + +## Status + +Emit: + +``` +[STATUS] Planning implementations +``` + +## Action + +### a. Select items + +Read the plan. Take items with `status: "proposed"`. If there are none, emit `[STATUS] No scaffolds to plan` and continue to the next step. + +### b. Plan each item in parallel + +Each item's plan is independent — it reads only that item's evidence and one product doc — so dispatch **one `Agent` subagent per `proposed` item, all in a single message**, and let them plan concurrently. Planning adapts real code to the project's style, which is judgment work, so run each subagent on `model: "sonnet"` — not a cheap model, but never anything heavier than sonnet. Wait for all to return, then aggregate in (c). Run no other tool between dispatch and collection. + +**Do not read the evidence files yourself.** Each item's evidence `file:line` list is already in the plan — pass it straight into the subagent's prompt; the subagent does the reading. Pre-reading here is the orchestrator doing the subagents' work sequentially, which defeats the fan-out and reads every file twice. + +Each subagent's `description`: `Plan `. Each subagent's `prompt`, with `<>` filled from the item's `proposed` entry and the canonical doc for its product (from the **Doc map** below): + +``` +You are a cross-sell planning subagent. Plan ONE illustrative example of a single PostHog integration and return it as JSON. Read-only — do not edit any file. + +Item: — PostHog +Evidence: +Canonical PostHog API doc: + +Read the evidence files so the plan anchors on the project's actual structure, imports, and style. Stay within the evidence files and the one doc — do not explore the wider tree. + +Scope: a **single representative example** — one file, one minimal change at the clearest call site from the evidence — that shows how the integration looks in this codebase. This is a starting point for the operator to replicate, NOT full coverage. Exactly one entry in `files`. Say so in `approach` ("example — replicate at the other sites"). + +Keep the example minimal and self-evidently safe: feature-gated where relevant, single provider, clearly commented, defaulting to current behavior. Right altitude per product: +- Feature Flags — replace one hardcoded toggle from the evidence with `posthog.isFeatureEnabled('')` (client) or `await posthog.isFeatureEnabled('', distinctId)` (server), defaulting to current behavior when the flag is undefined; note the flag must be created in PostHog. +- Error Tracking — add `posthog.captureException(error)` (client) / posthog-node capture (server) inside the specific catch blocks from the evidence, leaving existing logging intact. +- Product / Web Analytics gap — add a single static-named `posthog.capture('')` on the named surface, or enable `capture_pageview`/`capture_pageleave` in the existing init. +- LLM Observability — wrap the existing AI client with the `@posthog/ai` wrapper, preserving the current call signature; note the package install. +- Session Replay — add/adjust the `session_recording` block in the existing `posthog.init`. + +Return exactly this JSON (no prose): +{ + "id": "", + "plan": { + "files": [{ "path": "", "note": "" }], + "approach": "<2–4 sentences: where the integration hooks in, how it stays minimal and reversible, and any PostHog package that must be installed (PostHog packages only)>", + "snippet": "" + } +} +``` + +**Doc map** — fill `` per product: + +- Feature Flags — `https://posthog.com/docs/feature-flags/installation` +- Error Tracking — `https://posthog.com/docs/error-tracking/installation` +- Product / Web Analytics — `https://posthog.com/docs/product-analytics/capture-events` (and the bundled `references/best-practices.md`) +- LLM Observability — `https://posthog.com/docs/llm-analytics/installation` +- Session Replay — `https://posthog.com/docs/session-replay/installation` +- Surveys — `https://posthog.com/docs/surveys/installation` +- Logs — `https://posthog.com/docs/logs/installation` + +### c. Update the plan + +Collect the returned JSON. Read the plan, set each item's `plan` block from its subagent's result and flip its `status` to `planned`, and write the file back in full. `propose-only` items are unchanged. + +## Output + +Every `proposed` item is now `planned` with a non-null `plan` block; `propose-only` items are unchanged. diff --git a/transformation-config/skills/cross-sell-3000/references/5-scaffold.md b/transformation-config/skills/cross-sell-3000/references/5-scaffold.md new file mode 100644 index 00000000..4f6f5068 --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/5-scaffold.md @@ -0,0 +1,63 @@ +--- +next_step: 6-verify.md +--- + +# Step 5: Scaffold the planned integrations + +This step applies every `planned` item by editing project source, using parallel subagents — one per edit group. It does NOT run the project's verify command (Step 6) and does NOT write the report (Step 7). The plan is at `/tmp/posthog-cross-sell-plan.json`; the toolchain is at `/tmp/posthog-cross-sell-env.json`. + +## Status + +Emit: + +``` +[STATUS] Grouping scaffolds +[STATUS] Scaffolding viable products +``` + +## Action + +### a. Compute edit groups + +Read the plan. Take every item with `status: "planned"`. Group them so that **items sharing any file land in the same group** (connected components over each item's `plan.files`). No two subagents will edit the same file, so groups run concurrently without conflict. If no items are `planned`, emit `[STATUS] No scaffolds to apply` and continue. + +### b. Dispatch one subagent per group in a single message + +Make one `Agent` call per group, **all in a single message**, each on `model: "sonnet"` — scaffolding edits real code, so don't drop below sonnet, and never go above it. Wait for all to return; run no other tool between dispatch and collection. + +Each subagent's `description`: `Scaffold `. Each subagent's `prompt`, filling `<>` with the group's items copied out of the plan (id, product, and the full `plan` block — files, approach, snippet): + +``` +You are a cross-sell scaffolding subagent. Apply these PostHog integrations to the project source and return: . + +Integrations (copied from the plan — do not read the plan file yourself): + + — approach: — files: — snippet: > + +Rules: +- Read each target file before editing it. Anchor on the actual current code and adapt the snippet to the file's style (quotes, semicolons, imports). Line numbers in the plan may have drifted — match on code. +- Keep each scaffold minimal and reversible: feature-gate or clearly comment the addition (a brief `// PostHog — scaffolded by cross-sell` marker is good). Default to the project's existing behavior when a flag/exception path is undefined. +- Each item's plan is a single illustrative example (one file). Apply exactly that one change — do not extend it to the other call sites; the report tells the operator to replicate. +- Edit only the files in your items' plans. Create a new file only when the plan's `files` lists it as new. +- If a plan requires an official PostHog package that isn't installed, add it to the dependency manifest with a caret range. Do NOT install it yourself and never add a non-PostHog dependency. Report which package you added so the orchestrator can install once. +- Do not create example/demo routes, placeholder flags wired to nothing, or speculative code beyond the plan. +- If a scaffold can't be applied cleanly (the surface moved, the snippet conflicts with current code), do not guess — report that item as failed with a one-line reason. + +Return one line per item: scaffolded|failed — [+pkg: if you added one]. +``` + +### c. Install any added PostHog packages + +If any subagent reported adding a PostHog package to the manifest, run the env file's `install_cmd` once from `project_root`. If the install fails, note it on the affected items (Step 6 will catch the resulting build break). + +### d. Update the plan + +Read the plan, set each item's `status` to `scaffolded` or `failed` and its `notes` to the subagent's one-liner, and write the file back in full. + +## Output + +Every previously-`planned` item is now `scaffolded` or `failed`. Finish by emitting: + +``` +[STATUS] Scaffolded: products, failed +``` diff --git a/transformation-config/skills/cross-sell-3000/references/6-verify.md b/transformation-config/skills/cross-sell-3000/references/6-verify.md new file mode 100644 index 00000000..203ae8ed --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/6-verify.md @@ -0,0 +1,44 @@ +--- +next_step: 7-report.md +--- + +# Step 6: Verify the scaffolds + +This step confirms the edits from Step 5 landed and that the project still passes its own checks, promoting items from `scaffolded` to `verified` (or demoting to `failed`). It does NOT write the report (Step 7) and makes at most **one** repair pass. The plan is at `/tmp/posthog-cross-sell-plan.json`; the baseline is at `/tmp/posthog-cross-sell-env.json`. + +## Status + +Emit: + +``` +[STATUS] Verifying scaffolds +[STATUS] Re-running project checks +``` + +## Action + +### a. Mechanical spot-checks + +For each `scaffolded` item, confirm with one targeted `Grep` or `Read` that the integration is present: the expected PostHog API call exists at the named surface, a new file exists, an init block gained the expected key, an added package is in the manifest. Promote to `verified` on success; demote to `failed` (with `notes`) when the edit is missing or wrong. + +These checks are read-only and independent, so with more than two items dispatch them **all in one message** as parallel `Agent` subagents — `subagent_type: "Explore"`, `model: "haiku"`, one item each. Each subagent runs **at most one Grep or Read (no more than three tool calls)** and returns a single line: ` present|missing — `. Collect the verdicts and set statuses. With one or two items, just check them inline — don't pay dispatch overhead. The repair pass in (b) stays with you; never delegate edits to these subagents. + +### b. Re-run the project check + +If the env file's `verify_cmd` is set, run it once from `project_root` and compare against the baseline: + +- **Baseline passed, now passes** — done. +- **Baseline passed, now fails** — the failures are regressions from scaffolding. Identify which edited file each error points at, make **one** repair pass fixing obvious fallout (a missing import for the PostHog symbol, a type mismatch on a flag default, a stray comma), and re-run once. If it still fails, revert the offending item's edits (restore the original code; remove any new file and manifest entry it added) and mark that item `failed` with `notes: "reverted — broke "`. +- **Baseline already failed** — only confirm no **new** errors reference files this step edited; pre-existing failures are not yours to fix. + +### c. Update the plan + +Write the plan back in full with every item at a final status: `verified`, `failed`, or `propose-only`. + +## Output + +No item remains at `scaffolded` or `planned`. Finish by emitting: + +``` +[STATUS] Verified: of scaffolds +``` diff --git a/transformation-config/skills/cross-sell-3000/references/7-report.md b/transformation-config/skills/cross-sell-3000/references/7-report.md new file mode 100644 index 00000000..759ed03e --- /dev/null +++ b/transformation-config/skills/cross-sell-3000/references/7-report.md @@ -0,0 +1,81 @@ +--- +next_step: null +--- + +# Step 7: Write the cross-sell report and clean up + +The plan at `/tmp/posthog-cross-sell-plan.json` now has a final status on every item. This step renders it into exactly one new file at the project root — `posthog-cross-sell-report.md` — and deletes the `/tmp/` intermediates. Do not re-read earlier step files. + +## Status + +Emit: + +``` +[STATUS] Writing cross-sell report +``` + +## File-creation contract + +The **only** file this step creates is `posthog-cross-sell-report.md` at the project root. Do NOT create a separate summary file, sidecar JSON/CSV, or example/demo source files. + +One exception: the wizard's outer prompt asks for a brief summary file after the skill workflow completes (e.g. `./posthog-cross-sell-3000-report.md`). That file is owned by the wizard, not this skill — when asked, write a short summary there that links to `posthog-cross-sell-report.md` for the full detail. Do not duplicate the full report into it. + +## How to produce it + +The per-item sub-sections are read-only and independent, so fan them out and collapse the results. + +### a. Draft per-item sub-sections in parallel + +Dispatch **one `Agent` subagent per `verified`, `propose-only`, and `failed` item, all in a single message**. These render already-decided plan data — and, for scaffolded items, the actual on-disk code — into markdown, which is formatting, not judgment, so run them on `subagent_type: "Explore"` / `model: "haiku"`. Each subagent reads **only its own item's files and `plan`/`notes`** (do not explore the wider tree) and returns the markdown for exactly its one sub-section, matching the spec under **Report structure** for its status: + +- `verified` → a `## Scaffolded` sub-section +- `propose-only` → a `## Proposed (not scaffolded)` sub-section +- `failed` → a `## Needs attention` sub-section + +Run no other tool between dispatch and collection, and wait for all to return before assembling. + +### b. Assemble and write + +You (the orchestrator) write the aggregate sections yourself from the plan in memory — `## Summary`, `## Opportunity overview`, `## Next steps` — since each needs the whole result set at once. Then collapse the returned sub-sections under their headings in plan order (`## Scaffolded`, then `## Proposed (not scaffolded)`, then `## Needs attention` — omit any heading with no items), and write the whole report to `posthog-cross-sell-report.md` in one pass. + +## Report structure + +**Keep the whole report short** — it rides alongside the diff, it doesn't replace reading it. Aim for under a page: terse sub-sections, no long code blocks, one line per item wherever possible. Each scaffolded product is a single illustrative example, so the report points at it and tells the operator to replicate — it does not re-explain the code. + +### `## Summary` + +Two sentences: how many products fit, and that one illustrative example was scaffolded per viable product (the rest are proposals). Then a one-line count — scaffolded / proposed / failed — and **no git commit was made; review the diff and commit**. + +### `## Opportunity overview` + +One table, ordered by `fit` then `effort`: Product · Mode · Fit · Effort · Status · one-line value. + +### `## Scaffolded` (verified items) + +**One line per `verified` item**: **product** — what the example changes, at `path:line` (+ any PostHog package added) — then a short **Finish in PostHog** clause naming the one manual step to activate it. No code blocks; the diff shows the code. + +### `## Proposed (not scaffolded)` + +**One line per `propose-only` item**: **product** — the value in a phrase, and why it wasn't scaffolded (`skip_reason`). For `cross-sell` items, name the competitor it would consolidate. + +### `## Needs attention` (failed items) + +Only if any item is `failed`: one line each — what was attempted, why it failed (`notes`), whether anything was reverted. + +### `## Next steps` + +A short list: review the diff and commit; for each scaffolded product, do its **Finish in PostHog** step and replicate the example at the other sites; pick up the proposals when ready; re-run the skill to surface the next layer. + +## Cleanup + +After the report is written, delete the intermediates in **one** `Bash` call: + +``` +rm -f /tmp/posthog-cross-sell-opportunities.json /tmp/posthog-cross-sell-plan.json /tmp/posthog-cross-sell-env.json +``` + +Finish by emitting: + +``` +[STATUS] Cross-sell complete: scaffolded, proposed +``` diff --git a/transformation-config/skills/demo-feature-flags/config.yaml b/transformation-config/skills/demo-feature-flags/config.yaml new file mode 100644 index 00000000..62dbfb42 --- /dev/null +++ b/transformation-config/skills/demo-feature-flags/config.yaml @@ -0,0 +1,22 @@ +type: docs-only +template: description.md +description: Review a project's feature flags against the PostHog guide on {display_name} and generate a task list +tags: [feature-flags, best-practices] +variants: + - id: best-practices + display_name: feature flag best practices + tags: [feature-flags] + docs_urls: + - https://posthog.com/docs/feature-flags/best-practices.md + + - id: cleaning-up-stale-flags + display_name: cleaning up stale feature flags + tags: [feature-flags] + docs_urls: + - https://posthog.com/docs/feature-flags/cleaning-up-stale-flags.md + + - id: cutting-costs + display_name: cutting feature flag costs + tags: [feature-flags] + docs_urls: + - https://posthog.com/docs/feature-flags/cutting-costs.md diff --git a/transformation-config/skills/demo-feature-flags/description.md b/transformation-config/skills/demo-feature-flags/description.md new file mode 100644 index 00000000..52b66ccf --- /dev/null +++ b/transformation-config/skills/demo-feature-flags/description.md @@ -0,0 +1,25 @@ +# PostHog demo — {display_name} + +Read the bundled PostHog guide on {display_name}, then turn it into a concrete task list for this project. Read-only: inspect the project and the guide, propose tasks, and stop. Never edit source or mutate PostHog state. + +## What to do + +1. Read the bundled guide under `references/` (listed below). It is the source of truth for what good looks like. +2. **The moment you've finished reading it, form a plan and seed the task list — before scanning the project or doing anything else.** Turn the guide's recommendations into a plan and call `TaskCreate` right away, one task per area you intend to check. +3. Scan the project's feature flag usage — SDK setup, flag call sites, and how flags are defined and cleaned up — and refine the tasks (`TaskUpdate`) as each gap becomes concrete. Each task names the specific change, cites `file:line` where it applies, and stands on its own. + +## Task list + +As soon as you've read the bundled guide, **call `TaskCreate` immediately** — before scanning the project or starting any analysis — so the task pane isn't empty. Seed it with the plan you just formed: one broad item per best-practice area the guide covers. It's fine if the first list is incomplete — seed the high-level items you can infer, then call `TaskCreate` again (or `TaskUpdate` to refine existing items) every time your understanding sharpens. Use `TaskUpdate` to mark an item `in_progress` when you start checking it and `completed` when its task is written. Keeping the list current matters more than getting it right on the first call. + +Keep task titles broad and job-oriented — describe the area of work (e.g. "Auditing flag rollout hygiene", "Checking stale-flag cleanup", "Reviewing default-value fallbacks"), not the specific files, paths, or symbols involved. Adjust the names to the project and the guide's contents. + +## Reference files + +{references} + +## Key principles + +- **Guide-driven**: every task traces back to a recommendation in the bundled guide. No freelance findings. +- **Evidence-based**: cite `file:line` for anything tied to a location. +- **Read-only**: the output is the task list, not a code change. diff --git a/transformation-config/skills/remediate-3000/BUILD_NOTES.md b/transformation-config/skills/remediate-3000/BUILD_NOTES.md new file mode 100644 index 00000000..3d60e99d --- /dev/null +++ b/transformation-config/skills/remediate-3000/BUILD_NOTES.md @@ -0,0 +1,73 @@ +# remediate-3000 — build notes + +Status as of **2026-06-05**. The write-side companion to `audit-3000`. Share freely; update in-place as the skill evolves. + +## What this is + +`remediate-3000` consumes the single artifact `audit-3000` produces — `posthog-audit-report.md` at the project root — and applies the safe fixes to the project source. It inverts audit-3000's read-only contract (it edits source; that's the job) while keeping every other guardrail: it never mutates PostHog state, never runs git mutations, and creates exactly one new project-root file (`posthog-remediation-report.md`). + +| Step | File | Job | +|---|---|---| +| 1 | `1-intake.md` | Parse the audit report → classified plan at `/tmp/posthog-remediation-plan.json`. `[ABORT] No audit report found` when missing. | +| 2 | `2-baseline.md` | Detect package manager + verify command, record pre-edit baseline → `/tmp/posthog-remediation-env.json`. | +| 3 | `3-dependencies.md` | Manifest version bumps (SDK up-to-date findings) + install. Re-verifies latest versions against the registry. | +| 4 | `4-code-fixes.md` | All remaining `auto-fix` items via parallel subagents, one per **edit group** (connected components over shared files — no two subagents touch the same file). | +| 5 | `5-verify.md` | Mechanical spot-checks per fix + re-run of the baseline command; one repair pass max; revert on unfixable regressions. | +| 6 | `6-report.md` | Render `posthog-remediation-report.md`; delete `/tmp/` intermediates. Terminal. | + +## Design decisions worth knowing + +1. **Classification is decided at intake, deterministically.** Every finding becomes exactly one of: + - `auto-fix` — errors/warnings with a concrete file-level recommendation, plus mechanical suggestions (init-config additions, additive instrumentation on named surfaces). + - `posthog-side` — fixes that mutate PostHog state (insight edits, flag disabling). **Never executed.** Rendered as copy-paste prompts in the final report, each with re-verification built in — same pattern as audit-3000's stale-flag playbook. + - `skip` — greenfield product adoption (feature work, not remediation) and stylistic renames that would orphan existing insights (e.g. tense migrations). +2. **The plan file is the ledger.** audit-3000 has the wizard-seeded `audit_resolve_checks` MCP ledger; remediate-3000 runs through the wizard's generic `agent-skill` program where no ledger is seeded, so it owns its own plan JSON in `/tmp/` instead. Same role: every step patches statuses; the final report renders from it. +3. **Edit groups prevent subagent conflicts.** Findings often share files (PII removal and duplicate removal both touch the login page). Step 4 unions items into connected components over their file lists and dispatches one subagent per component — concurrency without write races. +4. **Anchor on code, not line numbers.** The audit's snippets were written against a possibly-stale read. Subagents must read the target file and adapt; if the code moved or conflicts, they fail the item with a reason rather than guessing. +5. **Baseline before, verify after, one repair pass, then revert.** Step 2 records whether typecheck/lint/build passed pre-edit so step 5 can tell regressions from pre-existing failures. A regression gets one repair pass; if still broken, the offending item's edits are reverted and the item is reported as failed. +6. **The operator commits, not the skill.** Git state is recorded (repo? dirty?) but never mutated. The report's Next steps section tells the operator to review the diff, commit, run the PostHog-side prompts, and re-run audit-3000 to confirm. + +## Running it + +### Build the skill + +From `context-mill/`: + +```bash +node scripts/build.js # one-shot build → dist/skills/remediate-3000.zip +node scripts/dev-server.js # watch mode on :8765 (phrocs does this for you) +``` + +### Run via the wizard + +```bash +cd +wizard --local-mcp --skill="remediate-3000" +``` + +The wizard's generic `agent-skill` program (`wizard/src/lib/programs/agent-skill/`) runs any context-mill skill by id, so no wizard code changes are needed. `--local-mcp` makes the wizard read local context-mill output instead of hosted skills. + +### Skill-content smoke test without the wizard + +```bash +cd +mkdir -p .claude/skills/remediate-3000 +unzip -o /dist/skills/remediate-3000.zip -d .claude/skills/remediate-3000 +# Then in Claude Code: "Run the remediate-3000 skill from +# .claude/skills/remediate-3000/SKILL.md. Walk every step in order." +``` + +## Validated end-to-end (2026-06-05) + +First full wizard run against `hot-or-not-demo/hot-or-not-ai-demo-main` (16 findings from a prior audit-3000 run): 8 verified, 2 failed-with-reason, 6 skipped, `tsc --noEmit` green. Two notable behaviors, both by design: + +- **The verify step caught a wrong audit recommendation.** The audit suggested `session_recording.minimumDurationMilliseconds` in client init config, but in posthog-js `^1.381.0` that property only exists on `SessionRecordingRemoteConfig` (project-settings controlled) — TypeScript rejected it (TS2353). The skill removed the field to keep the typecheck green and routed the item to "Needs manual attention" with the correct project-settings fix. Consider feeding this back to audit-3000's `6b-session-replay.md`. +- **A code-fix subagent refused an inapplicable fix.** `app/page.tsx` is a server component that only calls `redirect('/rate')`; the suggested landing-page capture would be dead code. The subagent failed the item with the correct alternative placement rather than guessing. + +**Wizard wrapper report:** the wizard's prompt assembler (`wizard/src/lib/agent/agent-prompt.ts` `skillPrompt()`) instructs every skill run to write `./posthog--report.md` after the workflow — the outro screen points at it. Step 6's file-creation contract explicitly allows this wizard-owned summary (short, linking to the full report). Do not re-add it to the forbidden list; the same conflict exists in audit-3000 (its runs leave `posthog-audit-3000-report.md` despite its contract forbidding it). + +## Open issues / known TODOs + +1. **Interactive confirmation.** The skill currently auto-applies everything classified `auto-fix`. A future wizard version could surface the step-1 plan in the TUI and let the operator toggle items before step 3 runs. +2. **PostHog-side execution.** When the wizard session has a PostHog MCP with write scopes, the `posthog-side` prompts could become an opt-in step (with explicit operator confirmation) instead of copy-paste prompts. +3. **Pairing nicety.** audit-3000's step 10 could mention remediate-3000 by name in its Next steps section so the two skills cross-link. diff --git a/transformation-config/skills/remediate-3000/config.yaml b/transformation-config/skills/remediate-3000/config.yaml new file mode 100644 index 00000000..c517adc0 --- /dev/null +++ b/transformation-config/skills/remediate-3000/config.yaml @@ -0,0 +1,16 @@ +type: docs-only +template: description.md +description: Remediate the findings of a PostHog audit-3000 run by applying safe fixes to the project source (v3000) +tags: [best-practices] +references: + preamble: "**Read ONLY this file.** Do not read any other reference file until this one tells you to." +shared_docs: + - https://posthog.com/docs/getting-started/identify-users.md + - https://posthog.com/docs/product-analytics/best-practices.md + - https://posthog.com/docs/session-replay/how-to-control-which-sessions-you-record.md + - https://posthog.com/docs/libraries/js/config.md +variants: + - id: all + display_name: PostHog remediate 3000 + tags: [best-practices] + docs_urls: [] diff --git a/transformation-config/skills/remediate-3000/description.md b/transformation-config/skills/remediate-3000/description.md new file mode 100644 index 00000000..4420de58 --- /dev/null +++ b/transformation-config/skills/remediate-3000/description.md @@ -0,0 +1,72 @@ +# PostHog Remediate 3000 + +This skill is the write-side companion to `audit-3000`. It consumes the audit report that skill produces (`posthog-audit-report.md` at the project root), turns every finding into a classified remediation plan, and **applies the safe fixes directly to the project source** — dependency bumps, identity fixes, PII removal, duplicate-event removal, event-name alignment, init-config additions, and instrumentation gap fills. Fixes that require mutating PostHog state (editing insights, disabling flags) are **never executed** — they are rendered as copy-paste prompts in the final report. Greenfield product adoption (new Surveys, Logs, LLM Observability, Feature Flags usage) is feature work, not remediation — those findings are listed as skipped with reasons. + +**Write contract.** Unlike the audit, this skill edits project source files — that is its job. But it only edits files named by a plan item (or files the item's recommendation explicitly describes), it never runs `git commit`, `git push`, or any other git mutation, it never mutates PostHog state through MCP, and it creates exactly **one** new file at the project root: `posthog-remediation-report.md`. Intermediate state lives in `/tmp/` while the chain runs (`/tmp/posthog-remediation-plan.json`, `/tmp/posthog-remediation-env.json`) and the final step deletes both. The operator reviews the diff and commits — not this skill. + +Perform only the fixes derived from the audit report. Do not hunt for new findings — re-running the audit is the operator's job, and the final report tells them to. + +## Workflow + +The remediation runs as a step chain. **The exact step list lives in the reference files themselves, not in this overview.** Step 1 lives at `references/1-intake.md`; each step file ends with a `next_step:` frontmatter pointer to the next, and the final step has `next_step: null`. Follow them in the order they point. You must resolve each step in order before any source-tree exploration. + +**Start by reading the path relative to this file at `references/1-intake.md`.** Do not Glob, ls, or find the skill directory. Do not preload future steps. Do not re-read a step file once you've moved past it. Do not re-read SKILL.md. + +`ToolSearch` is only for loading a tool by exact name when the SDK has it deferred (e.g. `select:Grep`). Do **not** use it to browse for other tools — every tool the remediation needs (`Glob`, `Grep`, `Read`, `Edit`, `Write`, `Bash`, `Agent`) is already named in this skill. + +**Do not call `TaskCreate` / `TaskUpdate` / `TaskGet` / `TaskList`.** The remediation doesn't track its own task list — progress comes from the plan file plus `[STATUS]` lines. + +## Remediation plan file + +The plan lives at `/tmp/posthog-remediation-plan.json` and is the single source of truth for what gets fixed. Step 1 creates it; later steps update item statuses by reading the file, patching it, and writing it back in full. Each item carries: + +- `id` — stable kebab-case slug derived from the finding's check name. +- `severity` — `error` | `warning` | `suggestion` (from the audit report). +- `area` / `check` — copied from the report's Problematic items table. +- `files` — every `path:line` the finding references. +- `summary` — the finding's Diagnosis, condensed to one or two sentences. +- `recommendation` — the report's full Recommended block, including code snippets. +- `classification` — `auto-fix` | `posthog-side` | `skip`. +- `skip_reason` — required when classification is not `auto-fix`. +- `status` — `planned` | `fixed` | `verified` | `failed` | `skipped`. +- `notes` — one-line record of what was changed or why it failed. + +## Severity ordering + +Within any step that applies fixes, `error` items are applied before `warning` items, and `warning` items before `suggestion` items. The most impactful fixes land first, so a partial run still leaves the project better off. + +## Key principles + +- **Plan-driven**: every edit traces back to a plan item, which traces back to a finding in the audit report. No freelance fixes. +- **Minimal diffs**: adapt the report's recommended snippet to the file's actual current code and style. Anchor on code, not on the report's line numbers — they may have drifted since the audit ran. +- **Fail safe**: if a fix can't be applied safely (code moved, conflicting change), mark the item `failed` with a reason instead of guessing. A failed item with a clear note beats a wrong edit. +- **Verify before reporting**: fixes are spot-checked mechanically and the project's own typecheck/lint/build is re-run against a baseline recorded before any edit. + +## Abort statuses + +Report abort states with `[ABORT]` prefixed messages. The wizard catches these and terminates the run — do not halt yourself. +- No audit report found + +## Reference files + +{references} + +## Framework guidelines + +## Task list + + As soon as you have a rough sense of the work, **call `TaskCreate` immediately** — before reading any reference file or starting analysis — so the task pane isn't empty. It's fine + if the first list is incomplete: seed it with the high-level items you can infer, then call `TaskCreate` again (or `TaskUpdate` to refine existing items) every time your + understanding sharpens. Use `TaskUpdate` to mark an item `in_progress` when you start it and `completed` when you finish. Keeping the list current matters more than getting it + right on the first call. + + Keep task titles broad and job-oriented — describe the purpose or area of work (e.g. "Planning the migration", "Wiring up auth", "Writing tests"), not the specific files, paths, + or symbols involved. Adjust the names to the user's project and context. + + ## Status + + Before beginning each phase or sub-step, emit a plain-text line with the exact prefix `[STATUS]`: + + [STATUS] Checking project structure + + The harness intercepts these and updates the "Working on …" banner. Use them freely — they are cheap. diff --git a/transformation-config/skills/remediate-3000/references/1-intake.md b/transformation-config/skills/remediate-3000/references/1-intake.md new file mode 100644 index 00000000..4e07704b --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/1-intake.md @@ -0,0 +1,71 @@ +--- +next_step: 2-baseline.md +--- + +# Step 1: Parse the audit report into a remediation plan + +This step locates `posthog-audit-report.md`, extracts every finding, classifies each one, and writes the plan to `/tmp/posthog-remediation-plan.json`. It does NOT edit any source file (steps 3–4 own edits), does NOT run any project toolchain command (step 2 owns that), and does NOT read project source beyond the report itself. + +## Status + +Emit: + +``` +[STATUS] Locating audit report +[STATUS] Building remediation plan +``` + +## Action + +### a. Locate the report + +`Read` `posthog-audit-report.md` at the project root. If it's not there, run **one** `Glob` for `**/posthog-audit-report.md` (ignore matches under `node_modules`, `.next`, `dist`, `build`) and read the first match. If no report exists anywhere, emit `[ABORT] No audit report found` and stop — the operator must run the `audit-3000` skill first. + +### b. Extract findings + +The report has a **Problematic items** table (one row per non-pass finding: Severity, Area, Check, File, Details) and a **Recommended actions** section (one numbered sub-section per finding with **Diagnosis**, **Why it matters**, **Currently**, **Recommended**, and **Sources** parts). For each table row, find its matching Recommended-actions sub-section by area + check name and build one plan item: + +- `id`: kebab-case slug of the check name (e.g. `cross-runtime-distinct-id`). +- `severity`, `area`, `check`: from the table row. +- `files`: every `path:line` mentioned in the row's File column **and** in the sub-section's Diagnosis (a finding can span several files). +- `summary`: the Diagnosis, condensed to one or two sentences. +- `recommendation`: the full Recommended block, verbatim, including fenced code snippets. + +A table row with no matching sub-section still becomes an item — `recommendation` stays empty and classification falls through to `skip` below. Findings under **Use case expansion & cross-sell** that already appear in the table (gap-mode rows) are the same item; do not duplicate them. + +### c. Classify each item + +Apply these rules in order; first match wins: + +1. **`posthog-side`** — the fix mutates PostHog state rather than the codebase: editing or renaming insights/dashboards, disabling or archiving feature flags, changing project settings, granting MCP scopes. `skip_reason`: "requires PostHog-side change — rendered as copy-paste prompt in the final report". Note: an event-name mismatch where the report recommends **renaming in code** is NOT this class — that's `auto-fix`. Only when the report recommends editing the PostHog insight does it land here. +2. **`skip`** — any of: a greenfield adoption finding (a PostHog product with no existing usage and no named code surface — e.g. "adopt Surveys", "adopt Logs", "adopt LLM Observability", "add Feature Flags"); a purely stylistic rename that would orphan existing PostHog insights (e.g. past-tense → present-tense event naming migration); an empty `recommendation`. Record the specific `skip_reason`. +3. **`auto-fix`** — everything else: `error` and `warning` items with a concrete file-level recommendation, plus `suggestion` items that are pure init-config additions (e.g. `session_recording` options) or additive instrumentation on a surface the report names by file (e.g. `captureException` in an existing catch block, a `capture` call on a named page). + +### d. Write the plan + +`Write` `/tmp/posthog-remediation-plan.json`: + +```json +{ + "report_path": "", + "project_root": "", + "items": [ + { + "id": "...", "severity": "...", "area": "...", "check": "...", + "files": ["path:line"], "summary": "...", "recommendation": "...", + "classification": "auto-fix|posthog-side|skip", + "skip_reason": null, "status": "planned", "notes": null + } + ] +} +``` + +`status` is `planned` for `auto-fix` items and `skipped` for everything else. + +## Output + +The plan file exists and its item count equals the Problematic-items row count. Finish by emitting: + +``` +[STATUS] Plan ready: auto-fix, posthog-side, skipped +``` diff --git a/transformation-config/skills/remediate-3000/references/2-baseline.md b/transformation-config/skills/remediate-3000/references/2-baseline.md new file mode 100644 index 00000000..3fb6034b --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/2-baseline.md @@ -0,0 +1,56 @@ +--- +next_step: 3-dependencies.md +--- + +# Step 2: Record the project toolchain and baseline + +The plan is at `/tmp/posthog-remediation-plan.json` (written by step 1). This step detects the project's package manager and verification command, runs that command once to record a pre-edit baseline, and writes `/tmp/posthog-remediation-env.json`. It does NOT edit anything (steps 3–4) and does NOT judge fixes (step 5). Do not re-read step 1. + +## Status + +Emit: + +``` +[STATUS] Detecting toolchain +[STATUS] Recording baseline +``` + +## Action + +### a. Detect the package manager and commands + +From the `project_root` recorded in the plan, identify the package manager by lockfile: `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `bun.lockb`/`bun.lock` → bun, `package-lock.json` → npm. For non-JS projects use the manifest the audit found (`requirements.txt`/`pyproject.toml` → pip/uv, `Gemfile` → bundler, `composer.json` → composer, `go.mod` → go, etc.). + +Pick **one** verification command, in preference order: + +1. A `typecheck` script in the manifest, else `tsc --noEmit` when `tsconfig.json` exists. +2. A `lint` script. +3. A `build` script. +4. None → record `verify_cmd: null`. + +### b. Record git state + +Run `git rev-parse --is-inside-work-tree` and, if a repo, `git status --porcelain`. Record whether the tree is dirty. **Record only** — do not commit, stash, branch, or otherwise mutate git state, and do not abort on a dirty tree. + +### c. Run the baseline + +If `verify_cmd` is set, run it once from `project_root`. Record whether it passed and, on failure, a one-line summary of the error count and the files involved — step 5 uses this to tell pre-existing failures apart from regressions caused by edits. Do not attempt to fix any baseline failure. + +### d. Write the env file + +`Write` `/tmp/posthog-remediation-env.json`: + +```json +{ + "package_manager": "pnpm", + "install_cmd": "pnpm install", + "verify_cmd": "pnpm typecheck", + "baseline_pass": true, + "baseline_summary": null, + "git": { "repo": true, "dirty": false } +} +``` + +## Output + +The env file exists with all six keys populated (nulls allowed where detection found nothing). diff --git a/transformation-config/skills/remediate-3000/references/3-dependencies.md b/transformation-config/skills/remediate-3000/references/3-dependencies.md new file mode 100644 index 00000000..3388744e --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/3-dependencies.md @@ -0,0 +1,41 @@ +--- +next_step: 4-code-fixes.md +--- + +# Step 3: Apply dependency fixes + +This step applies the plan items whose entire fix is a dependency-manifest version bump (e.g. an `sdk-up-to-date` finding). It does NOT touch source files (step 4) and does NOT run the project's verify command (step 5). The plan is at `/tmp/posthog-remediation-plan.json`; the toolchain is at `/tmp/posthog-remediation-env.json`. + +## Status + +Emit: + +``` +[STATUS] Updating PostHog SDK versions +``` + +## Action + +### a. Select items + +Read the plan. Select items with `status: "planned"` whose `recommendation` edits only dependency manifests (`package.json`, `requirements.txt`, `pyproject.toml`, `Gemfile`, `composer.json`, `go.mod`, …). If there are none, emit `[STATUS] No dependency fixes needed` and continue to the next step. + +### b. Re-verify target versions + +The audit's "latest" versions may have moved since the report was written. For each package, run **one** `Bash` registry lookup (`npm view version` for npm; the equivalent for other registries) and use the result as the target. + +### c. Edit the manifest + +Update each package's version range to the latest, **matching the project's existing range style** (`^`, `~`, or exact — copy whatever the manifest already uses). Edit only the PostHog packages the plan items name. + +### d. Install + +Run the `install_cmd` from the env file, from `project_root`. If the install fails, revert the manifest edit for the failing package and record the error. + +### e. Update the plan + +Read the plan, set each selected item's `status` to `fixed` (or `failed`) with a one-line `notes` (e.g. `posthog-js ^1.341.0 → ^1.381.0, install ok`), and write the file back in full. + +## Output + +The plan file reflects a terminal `fixed`/`failed` status for every dependency item, and the lockfile matches the edited manifest (install completed). diff --git a/transformation-config/skills/remediate-3000/references/4-code-fixes.md b/transformation-config/skills/remediate-3000/references/4-code-fixes.md new file mode 100644 index 00000000..020e27f8 --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/4-code-fixes.md @@ -0,0 +1,60 @@ +--- +next_step: 5-verify.md +--- + +# Step 4: Apply source-code fixes + +This step applies every remaining `auto-fix` plan item by editing project source, using parallel subagents — one per edit group. It does NOT run the project's verify command (step 5) and does NOT write the report (step 6). The plan is at `/tmp/posthog-remediation-plan.json`. Dependency items were finished in step 3 — only `status: "planned"` items remain in scope. + +## Status + +Emit: + +``` +[STATUS] Planning edit groups +[STATUS] Applying code fixes +``` + +## Action + +### a. Compute edit groups + +Read the plan. Take every item with `status: "planned"`. Group them so that **items sharing any file land in the same group** (connected components over the `files` lists — a multi-file fix keeps all its files in one group). This guarantees no two subagents ever edit the same file, so they can run concurrently without conflicts. + +### b. Dispatch one subagent per group in a single message + +Make one `Agent` tool call per group, **all in a single message** so they run concurrently. Wait for all of them to return; do not run any other tool between dispatch and collection. + +Each subagent's `description`: `Remediate `. Each subagent's `prompt` — fill in the `<>` placeholders with the group's items copied out of the plan (id, severity, files, summary, and the **full** `recommendation` text including code blocks): + +``` +You are a remediation subagent. Apply these fixes to the project source and return: . + +Fixes (extracted from the remediation plan — do not read the audit report or the plan file yourself): + + () — files: — followed by the full recommendation text> + +Rules: +- Read each target file before editing it. The audit's snippets and line numbers were written against an earlier read of the file and may have drifted — anchor every edit on the actual code, not on line numbers. Adapt the recommended snippet to the file's current style (quotes, semicolons, import ordering). +- Apply error items first, then warnings, then suggestions. +- Edit only the files listed for your items. Touching an unlisted file is allowed only when the recommendation explicitly describes it (e.g. adding a header to the client call-site that a server route now reads). +- When removing PII from event properties: remove only the named PII keys; keep the remaining properties and the capture call itself unless the recommendation says to delete the whole call. +- When removing a duplicate event: delete exactly the capture call the recommendation names; leave the surviving event untouched. +- When renaming an event: rename every occurrence in source (captures, tests, comments referencing the event name), and nothing else. +- Never run git commands, never install packages, never create new files unless the recommendation explicitly requires one. +- If a fix cannot be applied safely (the code moved, the recommendation conflicts with the file's current state, or two of your items contradict each other), do not guess — report that item as failed with a one-line reason and move on. + +Return exactly one line per item: fixed|failed — . +``` + +### c. Update the plan + +After all subagents return, read the plan, set each item's `status` to `fixed` or `failed` and its `notes` to the subagent's one-liner, and write the file back in full. + +## Output + +Every previously-`planned` item has a terminal `fixed`/`failed` status in the plan. Finish by emitting: + +``` +[STATUS] Code fixes applied: fixed, failed +``` diff --git a/transformation-config/skills/remediate-3000/references/5-verify.md b/transformation-config/skills/remediate-3000/references/5-verify.md new file mode 100644 index 00000000..42fa83a2 --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/5-verify.md @@ -0,0 +1,42 @@ +--- +next_step: 6-report.md +--- + +# Step 5: Verify the fixes + +This step confirms the edits from steps 3–4 actually landed and that the project still passes its own checks, promoting plan items from `fixed` to `verified` (or demoting to `failed`). It does NOT write the report (step 6) and it makes at most **one** repair pass. The plan is at `/tmp/posthog-remediation-plan.json`; the baseline is at `/tmp/posthog-remediation-env.json`. + +## Status + +Emit: + +``` +[STATUS] Verifying fixes +[STATUS] Re-running project checks +``` + +## Action + +### a. Mechanical spot-checks + +For each `fixed` item, confirm with one targeted `Grep` or `Read` that the change is present: a removed property key no longer appears in that capture call, an added config key exists in the init options, a renamed event's old name is gone from source, a new `identify`/`captureException` call exists at the named surface. Promote to `verified` on success; demote to `failed` (with `notes`) when the edit is missing or wrong. + +### b. Re-run the project check + +If the env file's `verify_cmd` is set, run it once from `project_root` and compare against the baseline: + +- **Baseline passed, now passes** — done. +- **Baseline passed, now fails** — the failures are regressions. Identify which edited file each error points at, make **one** repair pass fixing obvious edit fallout (an unused import left behind, a missing comma, a renamed symbol referenced elsewhere), and re-run the command once. If it still fails, revert the offending item's edits (restore the original code at those sites) and mark that item `failed` with `notes: "reverted — broke "`. +- **Baseline already failed** — only confirm no **new** errors reference files this skill edited; pre-existing failures are not yours to fix. + +### c. Update the plan + +Write the plan back in full with every item at a final status: `verified`, `failed`, or `skipped`. + +## Output + +No item remains at `planned` or bare `fixed`. Finish by emitting: + +``` +[STATUS] Verified: of fixes +``` diff --git a/transformation-config/skills/remediate-3000/references/6-report.md b/transformation-config/skills/remediate-3000/references/6-report.md new file mode 100644 index 00000000..8b23ddea --- /dev/null +++ b/transformation-config/skills/remediate-3000/references/6-report.md @@ -0,0 +1,67 @@ +--- +next_step: null +--- + +# Step 6: Write the remediation report and clean up + +The plan at `/tmp/posthog-remediation-plan.json` now has a final status on every item. This step renders it into exactly one new file at the project root — `posthog-remediation-report.md` — and deletes the `/tmp/` intermediates. Do not re-read earlier step files. + +## Status + +Emit: + +``` +[STATUS] Writing remediation report +``` + +## File-creation contract + +The **only** file this step creates is `posthog-remediation-report.md` at the project root. Do NOT create `posthog-remediation-summary.md`, sidecar JSON/CSV exports, or any other file. Do NOT edit `posthog-audit-report.md`. + +One exception: the wizard's outer prompt asks for a brief summary file after the skill workflow completes (e.g. `./posthog-remediate-3000-report.md`). That file is owned by the wizard, not this skill — when asked, write a short summary there that links to `posthog-remediation-report.md` for the full detail. Do not duplicate the full report into it. + +## Report structure + +### `## Summary` + +One paragraph: what was remediated and the overall outcome. Then a counts line: verified / failed / posthog-side / skipped, and a note that **no git commit was made** — the operator reviews the diff and commits. + +### `## Changes applied` + +One sub-section per `verified` item: area · check, severity badge, files edited as `path:line`, and a 2–4 sentence description of what changed. Where the change is short, show a before/after fenced snippet read from the edited file (the **actual** new code, not the audit's proposal). + +### `## Needs manual attention` + +One sub-section per `failed` item: what was attempted, why it failed (the `notes` field), whether anything was reverted, and what the operator should do by hand — including the original recommendation from the plan so the report stands alone. + +### `## PostHog-side actions` + +For each `posthog-side` item, render a fenced **copy-paste prompt** the operator can paste into any PostHog MCP-enabled chat. Each prompt must (1) name the exact PostHog artifacts involved (insight names, flag keys), (2) instruct the assistant to re-verify current state before mutating anything, and (3) describe the change in one sentence. Example shape: + +``` +Using the PostHog MCP tools: find the insights that reference the event +"". Verify each still references it, then update them to +reference "" instead. List every insight you changed. +``` + +### `## Skipped` + +A table of `skipped` items: check, severity, reason. Greenfield adoption items get one sentence pointing at the relevant PostHog product docs. + +### `## Next steps` + +Tell the operator to: review the working-tree diff and commit; run the PostHog-side prompts; and re-run the audit (`posthog-wizard` with the `audit-3000` skill) to refresh the ledger and confirm the findings are resolved. + +## Cleanup + +After the report is written, delete the intermediates in **one** `Bash` call: + +``` +rm -f /tmp/posthog-remediation-plan.json /tmp/posthog-remediation-env.json +``` + +Finish by emitting: + +``` +[STATUS] Remediation complete: fixed, need manual follow-up +```