Skip to content

fix(wizard-tools): compare canonical paths in resolveEnvPath - #1257

Draft
posthog[bot] wants to merge 2 commits into
mainfrom
posthog-self-driving/fixwizard-tools-normalize-the-install-3d7e82
Draft

posthog[bot] wants to merge 2 commits into
mainfrom
posthog-self-driving/fixwizard-tools-normalize-the-install-3d7e82

Conversation

@posthog

@posthog posthog Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Problem

  • A user runs the wizard with a non-canonical install dir (a trailing slash, or a relative path). The SDK lands in their project, then the run aborts and no PostHog token is ever written.
  • resolveEnvPath decided "inside the workspace" with a raw string compare against workingDirectory, which it never normalised. /project/ + .env resolves to /project/.env, which does not start with /project//, so a plain .env was refused as path traversal.
  • Nothing upstream canonicalised the value: the interactive runner stored the flag as given, and resolveProjectDir returns the install dir untouched for a project at the repo root.
  • The refused write failed the init task, and a required task failure aborts the whole orchestrator run — identify, error tracking, capture, review and dashboard never ran.
  • The rejection branch captured no analytics, so the failure was invisible in telemetry.

Changes

  • Compare canonical paths. resolveEnvPath resolves the working directory before it compares, so a directory that is only spelled differently is the same directory. Real traversal (../, absolute paths) is still refused.
  • Canonicalise once at the source. buildSession stores path.resolve(installDir), so every consumer of session.installDir gets a resolved path.
  • Make the refusal measurable. The rejection branch now sends env path traversal rejected with the requested file name, whether the request was absolute, and the platform. Both tool facades (pi and MCP) call the same helper, so both are covered.

Test plan

  • pnpm vitest run — 2716 tests pass.
  • New unit test covers a trailing separator, a . segment and a relative working directory, and confirms ../.env is still refused.
  • pnpm typecheck error count is unchanged from main (27 pre-existing).
  • Prettier and ESLint clean on the changed files.

LLM context

Not changed, and worth a separate decision: the report also asks that an env-write failure after code init has landed should not take the rest of the orchestrator down. That is not a path bug — it is the run verdict treating any required task failure as fatal (orchestrator-runner.ts), and which tasks are required comes from the planner rather than this repo. Making init non-fatal would let a run report success with PostHog code and no token, which is worse than the abort. Left as-is deliberately.


Created with PostHog Desktop from this inbox report.

🤖 Generated with Claude Code

A working directory with a trailing separator or a relative spelling made
every env write look like path traversal, so the run installed the SDK and
then aborted without a token.

Canonicalise the install dir once in buildSession, compare resolved paths in
resolveEnvPath, and capture an analytics event on the rejection branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 264725c8-f2e9-4788-b71c-95b188c7b4cf
@posthog

posthog Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

🦔 PostHog Review reviewed this pull request

Nothing worth raising this time, so here's a calming picture instead:

A panda relaxing and waving

Resolved comments: 1 already settled

@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@posthog

posthog Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostHog Review

Found 1 consider.

Comment thread src/lib/wizard-tools/tools.ts Outdated
A file-system or drive root already ends with the separator, so appending one
built a `//` prefix that no valid child path starts with. Build the prefix from
the root's own trailing separator instead of string arithmetic.

The comparison stays case-sensitive, so the guard is not relaxed beyond the
root case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 264725c8-f2e9-4788-b71c-95b188c7b4cf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants