6.6 KiB
id, title, status, wave, depends_on, plan, requirements, acceptance_criteria, system_design
| id | title | status | wave | depends_on | plan | requirements | acceptance_criteria | system_design | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-local-agent-path | Preserve local agent PATH | done | 1 | plan.md |
|
|
|
Task 01: Preserve local agent PATH
Summary
Make the shared Unix backend child environment include the runtime user's local executable directory. Prove newly installed Cursor is discovered and executable without restarting solely to refresh PATH.
Scope and owned files
apps/backend/internal/launcher/env.go: invoke the normalizer after overrides.apps/backend/internal/launcher/local_agent_path.goandlocal_agent_path_test.go: focused helper and producer/consumer regressions.- Existing launcher supervisor tests if needed to verify restart propagation.
docs/public/cli.md: describe supported local agent discovery after the fix.
Do not change Cursor identity, permissions, shell profiles, UI markup, remote execution, service accounts, or npm shim behavior.
Inputs
Read the linked requirement/design and plan evidence. Use
service_npm_path_test.go as a subprocess fixture pattern. Trace start.go,
dev.go, supervisor.go, and local agentctl environment inheritance before edits.
Acceptance
- The post-install and launchd regression tests fail for missing discovery before the patch, then pass through the real environment producer.
- Preserve ordering, effective home, idempotence, Windows behavior, and absence semantics; cover all criteria in the plan's test matrix.
- Actual child execution and restart propagation pass; record isolated macOS regular/service smoke results or explicitly retain that validation gap.
Verification
From the repository root, run the focused regression first for red/green, then the package checks:
(cd apps/backend && go test ./internal/launcher -run '^TestLocalAgentPath' -count=1)
(cd apps/backend && go test -race ./internal/launcher ./internal/agent/agents ./internal/agent/runtime/agentctl/launcher -count=1)
python3 scripts/list-docs.py validate
python3 scripts/lint-spec-files.py --all
git diff --check
Use a writable GOCACHE override when the default cache is read-only. macOS smoke
steps: start an isolated owned regular runtime with .local/bin absent from
inherited PATH; install Cursor through settings; rescan and verify detection and
local probe execution. Repeat with an isolated owned launchd service. Never
replace or restart the user's main service for this check. Remove owned fixtures.
Risks
Do not use Kandev data home as user home or normalize before final HOME/PATH overrides. Preserve configured executable precedence and do not rely on the directory existing at startup. Keep auth failure separate from binary discovery.
Parallelism
sequential
Results
Implemented in env.go and local_agent_path.go; regression coverage is in
local_agent_path_test.go. Public CLI documentation updated.
GOCACHE=/tmp/kandev-cursor-go-cache go test ./internal/launcher -run '^TestLocalAgentPath' -count=1: passed after failing on missing discovery before the patch.GOCACHE=/tmp/kandev-cursor-go-cache go test -race ./internal/launcher ./internal/agent/agents ./internal/agent/runtime/agentctl/launcher -count=1: both agent packages passed; launcher required the isolated rerun below because the sandbox forbids sockets and inherited runtime settings conflict with fixture values.- Launcher rerun outside the socket-restricted sandbox: Python copied
os.environexcluding keys starting withKANDEV_, setGOCACHE=/tmp/kandev-cursor-go-cache, and rango test -race ./internal/launcher -count=1. Passed (14.310s). python3 scripts/list-docs.py validate: passed.python3 scripts/lint-spec-files.py --all: passed.git diff --check: passed.- Final lint correction reused the existing
goosWindowsconstant; the focused regression suite was rerun with-raceafterward. pnpm install --frozen-lockfilefromapps/: passed for commit-hook dependencies.
Native macOS regular/service smoke testing was not available on this Linux runner. The generated launchd environment, actual discovery, executable precedence, late installation, absence behavior, and supervised restart are covered by process-level tests. Windows preservation is included as a platform-conditional test but was not executed on Windows here.
PR review remediation
Codex identified that a system LaunchDaemon can inherit an absent or incorrect
HOME after selecting a non-root account. System-service local executable PATH
now uses the effective UID's account home and preserves PATH when lookup fails.
Added local_agent_service_path_test.go with a generated non-root LaunchDaemon
fixture, actual discovery/execution, and failed/invalid account lookup coverage.
Regular launches retain final child HOME precedence.
Claude's delayed summary suggestion is addressed with a comment on
launchdServicePath explaining that runtime normalization supplies the user
executable directory because launchd has no home-directory specifier. This
clarification changes no executable behavior.
CodeRabbit's summary suggestion is addressed by documenting the usable absolute home condition in the requirement and public CLI guide.
Remediation validation:
GOCACHE=/tmp/kandev-cursor-go-cache go test -race ./internal/launcher -run '^TestLocalAgentPath' -count=1: passed.go test -race ./internal/launcher -count=1with inheritedKANDEV_*settings removed, writable GOCACHE, and local socket access: passed (16.928s).python3 scripts/list-docs.py validate,python3 scripts/lint-spec-files.py --all, andgit diff --check: passed.
Remote CI/review evidence remains pending for the remediation head.
CI test remediation
Backend shard 2 failed in TestCompletedTaskFollowUpAdmissionIsConversationalOnly
because the follow-up raced unfinished terminal-step session preparation.
The test now joins the existing onProcessOnEnterComplete signal before
admitting the follow-up. Its behavior assertions are unchanged; no production
contract or public documentation change is needed.
With inherited KANDEV_* settings removed and writable GOCACHE,
go test -race ./internal/orchestrator -run '^TestCompletedTaskFollowUpAdmissionIsConversationalOnly$' -count=20
reproduced the original assertion failure in root and child cases (189.376s),
then passed after synchronization (191.113s). Remote suite validation remains
pending for the new test-fix head.