Skip to content

[Bug]: GoCode cannot start Homebrew-installed harnessd from a selected workspace #1037

Description

@dennisonbertram

Work type

Bug / regression

Observed behavior

On 2026-07-30, the GoCode macOS app failed after selecting a folder. Its startup UI reported: harnessd exited during startup (code 1) and load prompt engine from prompts: open prompts/catalog.yaml: no such file or directory.

Expected behavior

When the app locates a Homebrew-installed harnessd, it must supply absolute prompts and catalog paths from that installation. Selecting any workspace must start the daemon without requiring a prompts/ directory inside the workspace.

Reproduction

  1. Install via the Formula layout: bin/harnessd, share/go-code/prompts/catalog.yaml, and share/go-code/catalog/.
  2. Launch GoCode and select a workspace that is not the GoCode source tree.
  3. Actual: process starts with workspace as cwd, no prompt directory is resolved, and exits. Reproduction is deterministic for this layout.

User and operational impact

The primary macOS folder-selection path is blocked for Homebrew installations. No data loss or security exposure; retry cannot recover. This is a regression because the formula explicitly installs the required resources separately.

Suspected seam and search evidence

Owner: macapp/Sources/HarnessKit/HarnessSupervisor.swift (findInstallationRoot, installationEnvironment) and macapp/Sources/GoCodeUI/ProjectSession.swift (HarnessBinary.canBoot). Search: rg -n "catalog.yaml|HARNESS_PROMPTS_DIR|harnessd" found the formula installs resources at share/go-code, whereas both resolvers only walk upward from the executable. cmd/harnessd/main.go honours HARNESS_PROMPTS_DIR; its failure text proves that variable was absent. Adjacent repo-local and PATH resolution already have tests.

Blast-radius impact map

  • Callers/data flow: ProjectSession locates the binary, then HarnessSupervisor constructs child env; both must agree on bootability.
  • Config/env/defaults: affected HARNESS_PROMPTS_DIR, model/pricing catalog env vars, optionally source root; app does not override caller-provided values.
  • API/CLI/wire formats/tools: None — daemon HTTP contract unchanged.
  • Persistence/schema/cache: None — only launch-time resource discovery.
  • Lifecycle/retries: startup failure becomes ready once correct environment is passed; Try Again remains unchanged.
  • Security/auth/privacy: None — only absolute local read paths from the selected executable’s installation prefix.
  • TUI/web/macOS clients: macOS app affected; TUI and direct CLI retain existing cwd discovery.
  • Provider/model/tool catalog: absolute model/pricing paths must remain populated under Homebrew layout.
  • Deployment/observability/runbooks: Formula layout is the rollout target; existing startup stderr is the diagnostic signal.
  • Compatibility: preserve repo-local layout and no-resource failure behavior.
  • Tests/fixtures: extend HarnessKit resource tests and UI bootability selection tests.
  • Documentation: engineering log + docs indexes as required; formula is already correct.

Regression test first

Test: a synthetic Homebrew prefix with bin/harnessd and share/go-code/{prompts/catalog.yaml,catalog/models.json,catalog/pricing.json}.
Red command: cd macapp && swift test --filter SupervisorResourceTests.
Expected failure before implementation: findPromptsDirectory and installationEnvironment return nil/empty for that layout. This proves the current app cannot supply required resources; include a no-catalog control.

Fix boundaries

In scope: repair the existing installation-root/resource resolver and HarnessBinary bootability check to recognize the Formula's installed layout; add permanent regression tests and engineering log entry. Out of scope: changing harnessd prompt lookup, Formula paths, app packaging, or unrelated UI changes. No parallel abstraction: both callers share the existing resolver.

Diagnostic and observability evidence

Screenshot records process exit 1 and relative prompts/catalog.yaml failure. Post-fix proof: supervisor environment contains absolute prompt/model/pricing paths and a real spawned daemon health check succeeds from an arbitrary workspace. No credentials in logs.

Verification plan

  1. Record the focused Swift test red.
  2. Implement minimal resolver change and run that test green.
  3. Run cd macapp && swift build && swift test and format/lint.
  4. Run macapp/scripts/live-test.sh to exercise a supervised real harnessd from a non-repo workspace.
  5. Open the rebuilt native app, select a folder, and verify it reaches the chat-ready state; inspect stderr/console for errors.
  6. Run repository regression gate before merge.

Rollout and rollback

Release an app build containing the resolver. Monitor startup error reports for relative prompt paths. Roll back by reinstalling the prior app build; no data migration or repair.

Documentation and handoff

Add a dated engineering-log entry, update relevant docs indexes if they list it, and link exact red/green/live evidence in the PR.

Definition of done

  • Deterministic reproduction recorded

  • Regression test failed before the fix

  • Existing resource resolver supports Formula layout

  • Repo-local and no-resource cases remain covered

  • Focused, full Swift, live-harness, and real app folder-selection paths pass

  • Engineering log and rollout evidence are current

  • I will preserve the failing regression test, update the issue if the root cause changes, and record any newly discovered bug as its own issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions