Skip to content

feat: workspace discovery and run provenance - #432

Merged
jahvon merged 6 commits into
mainfrom
feat/workspace-discovery
Aug 2, 2026
Merged

feat: workspace discovery and run provenance#432
jahvon merged 6 commits into
mainfrom
feat/workspace-discovery

Conversation

@jahvon

@jahvon jahvon commented Aug 2, 2026

Copy link
Copy Markdown
Member

Summary

Today flow can only resolve a workspace by name from the user config, so a git worktree or a fresh clone has to be registered before any executable will run. This adds directory-based discovery: flow walks up from the working directory to the nearest flow.yaml, the way make/bazel find their root, so registration becomes an optimization rather than a prerequisite.

  • A discovered workspace is named for its directory and lives in memory only — overlay caches layer it over the persisted ones so a throwaway clone can never shadow a real registered workspace.
  • Closest root wins, and a workspace's flow-file scan now stops at nested workspace boundaries, so a worktree checked out inside a repo no longer duplicates its parent's executables.
  • --workspace / FLOW_WORKSPACE accept a name or a path and are honored in fixed mode too; discovery itself applies in dynamic mode.
  • MCP tools (execute, run_command, run_executable, list_executables) gain a dir parameter and set the subprocess working directory, so an agent operating in a worktree runs against its directory instead of the server's.

Also fixes two pre-existing bugs surfaced along the way:

  • Dynamic-mode workspace scanning picked the first map match instead of the longest, and stripped /private from only one side of a path comparison.
  • The test-mode fallback logger used os.NewFile(0, os.DevNull), which adopts fd 0 (stdin) instead of opening the null device, and allocated a new file per call — each with its own finalizer waiting to close whatever descriptor it ended up holding. Under -coverprofile, GC could close stdin mid-run and hand the freed descriptor to the coverage writer, causing sporadic EBADF failures. Fixed to open /dev/null once and reuse it.

Plus a flaky-test fix (provenance tests now clear ambient FLOW_RUN_SESSION state instead of depending on it) and small housekeeping: consolidated dev-setup steps into a setup skill, tightened .claude/settings.json, and made the container e2e test check that Docker/Podman is actually running, not just on PATH.

Docs

  • New docs/guides/workspaces.md section on unregistered workspaces.
  • docs/guides/ai-tools.md updated for the new dir parameter on MCP tools.

jahvon and others added 6 commits July 28, 2026 19:32
….yaml

flow could only resolve a workspace by name from the user config, so a git
worktree or a fresh clone had to be registered before any executable would
run. Discovery now walks up from the working directory to the nearest
flow.yaml, the way make and bazel find their root, and registration becomes
an optimization rather than a prerequisite.

A discovered workspace is named for its directory and lives in memory only:
overlay caches layer it over the persisted ones so a throwaway clone can
never shadow a real workspace for a later command. Closest root wins, and a
workspace's flow file scan now stops at nested workspace boundaries, so a
worktree checked out inside a repo no longer duplicates its parent's
executables.

Discovery applies in dynamic mode; --workspace and FLOW_WORKSPACE accept a
name or a path and are honored in fixed mode too. MCP tools gain a `dir`
parameter and set the subprocess working directory, so an agent working in a
worktree no longer runs against the server's directory instead of its own.

Also fixes: the dynamic-mode workspace scan picked the first map match rather
than the longest, and stripped /private from only one side of the comparison.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mcpProvenance prefers an inherited FLOW_RUN_SESSION over one it mints, but
the subtests covering the mint-our-own fallback never cleared that variable.
Running them from inside a harness that exports it — an agent session, or CI
— failed on that machine and passed on every other one.

Clear both provenance variables for the test; the subtests that want an
inherited value already set their own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jahvon
jahvon merged commit bf4d890 into main Aug 2, 2026
15 checks passed
@jahvon
jahvon deleted the feat/workspace-discovery branch August 2, 2026 23: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