Skip to content

fix(cli): run unit and integration tests, and every mutant, in a throwaway home - #832

Merged
blafourcade merged 1 commit into
nextfrom
fix/tests-never-reach-the-real-profile
Sep 10, 2026
Merged

fix(cli): run unit and integration tests, and every mutant, in a throwaway home#832
blafourcade merged 1 commit into
nextfrom
fix/tests-never-reach-the-real-profile

Conversation

@blafourcade

Copy link
Copy Markdown
Contributor

🎯 What & why

A unit or integration test that relocated only AIDD_USER_CONFIG_DIR was one mutant away from the real profile. A Stryker mutant that drops that override sends the test to ~/.config/aidd of whoever runs the mutation. The mutant is killed, because the test fails, but the file is already written. On one machine this left a test marketplace entry (/src/framework) in the real registry, and replaced the real auth.json with a test token (#831).

🛠️ How it works

  • tests/helpers/throwaway-profile.ts is a global setup. It points HOME, USERPROFILE and APPDATA at a temp home, and unsets AIDD_USER_CONFIG_DIR, AIDD_TELEMETRY_DIR and XDG_CONFIG_HOME. Every route to a profile then ends in that temp home, which is removed on teardown.
  • It is declared on the unit and integration projects of both vitest.workspace.ts and vitest.mutation.config.ts.
  • It runs in the main process on purpose. Stryker runs vitest in worker threads, and a thread's own process.env never reaches os.homedir(). A first version with setupFiles passed in forks and still left os.homedir() on the real home under threads. The guard test caught it with --pool threads.

🧪 How to verify

  • tests/helpers/throwaway-profile.unit.test.ts: every resolver (os.homedir(), resolveHomeDir(), resolveAiddConfigDir(), userConfigDir()) lands under the temp directory, and no override is set.
    • Red before the fix: /Users/<me>: expected false to be true.
    • Red with a per-file setup under --pool threads.
    • Green now in threads and in forks.
  • tests/architecture/throwaway-profile-wiring.arch.test.ts: all four projects declare the setup. It was red before the wiring.
  • Mutant reproduction: rewrite if (process.env.AIDD_USER_CONFIG_DIR) return to if (false) return in src/runtime/user-config-dir.ts, then run marketplace-register-framework-use-case.integration.test.ts with HOME set to a stand-in developer home.
    • Before: the stand-in home receives .config/aidd/marketplaces.json.
    • After, in threads: the mutant is killed and the stand-in home stays empty.
  • A real node scripts/run-mutation.mjs tools-copilot --force passes its initial run. The real ~/.config/aidd is unchanged before and after it.

Local results on this branch:

Check Result
typecheck, lint, knip, type honesty pass
architecture 128 passed
unit + integration 5021 passed
e2e 297 passed
mutation, tools-copilot score 82.2, floor 80. Real ~/.config/aidd unchanged
leftover temp homes after the run 0

⚠️ Heads-up

🔗 Linked issue

Fixes #831

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

🤖 Generated with Claude Code

https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb

…waway home

A test that relocated only AIDD_USER_CONFIG_DIR was one mutant away from the real
profile: a mutant dropping that override sent it to ~/.config/aidd of whoever ran
the mutation. The mutant was killed, and the file was already written. One run left
a test marketplace entry in a real registry, and another overwrote a real auth.json
with a test token.

A global setup, shared by the suite's and the mutation run's unit and integration
projects, points HOME, USERPROFILE and APPDATA at a temp home and unsets the
overrides, so every route to a profile ends there. It runs in the main process
because Stryker runs vitest in worker threads: a thread's own process.env never
reaches os.homedir(), so a per-file setup left that route on the real home.

One test proves what a test sees, in threads and in forks. One proves all four
projects declare the setup.

Fixes #831

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb
AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60
@blafourcade
blafourcade requested a review from a team as a code owner September 10, 2026 16:41
@blafourcade
blafourcade merged commit 8c5f820 into next Sep 10, 2026
36 checks passed
@blafourcade
blafourcade deleted the fix/tests-never-reach-the-real-profile branch September 11, 2026 07:42
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.

1 participant