Skip to content

feat: inject a neutral per-project workspace layout#1244

Open
joshuajbouw wants to merge 13 commits into
mainfrom
agent/neutral-workspace-layout
Open

feat: inject a neutral per-project workspace layout#1244
joshuajbouw wants to merge 13 commits into
mainfrom
agent/neutral-workspace-layout

Conversation

@joshuajbouw

@joshuajbouw joshuajbouw commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Closes #1243

Summary

Introduces one validated neutral project workspace layout while preserving .astrid as standalone Astrid's exact default and leaving global AstridHome behavior unchanged.

Changes

  • add the typed WorkspaceLayout input and a global CLI --workspace-state-dir / ASTRID_WORKSPACE_STATE_DIR selection
  • propagate one process selection through daemon children, config, capsule install/update/remove, discovery, hooks, WIT GC, kernel boot, and gateway source verification
  • preserve existing public Rust entry points with default-layout wrappers
  • publish atomic readiness metadata bound to the selected project root and layout, derive its opaque selection fingerprint with the existing BLAKE3 primitive, and keep newly created readiness state directories private with Unix mode 0700
  • check readiness metadata before and after every workspace-sensitive CLI handshake so a mismatched CLI does not authenticate against the wrong daemon and a concurrent daemon restart cannot retarget an established client
  • reconnect long-lived MCP uplinks transactionally: construct and authenticate a checked replacement first, reject named-principal anonymous fallback, and swap only after both workspace checks succeed
  • apply the workspace invariant to session, kernel-management, admin, invite-redeem, capsule live-load/unload, MCP, headless, bootstrap, status, doctor, ps, top, and who paths
  • resolve bootstrap's selected workspace once and use it consistently for daemon spawn, client handshake, and model configuration
  • keep daemon stop deliberately global as the recovery path for a daemon serving another project or layout
  • preserve stale/unreachable socket behavior for capsule live-load and unload with an unauthenticated reachability probe while keeping reachable selection mismatches fail-closed
  • use explicit daemon workspace roots in gateway and hook discovery
  • keep user-level and workspace-level capsule updates in their original scope
  • add selection, handshake-order, restart-race, recovery-scope, reconnect-transaction, authentication, explicit-bootstrap-root, and stale-socket classification regressions plus an Unreleased changelog entry

Verification

  • cargo fmt --all -- --check
  • git diff --check
  • cargo metadata --locked --no-deps --format-version 1
  • direct-connection audit leaves KernelClient::connect, SocketClient::connect, and AdminClient::connect only behind the centralized workspace connector or the explicit stop/recovery bypass
  • focused regressions cover mismatch-before-connect, matching pre/post checks, post-connect retarget rejection, transactional reconnect replacement, reconnect-state re-arming, named-principal authentication, explicit bootstrap workspace propagation, global recovery scope, and offline-versus-selection classification
  • full compilation, tests, Clippy, public API, and platform coverage run in repository CI because newly compiled Rust executables on the local macOS host stall before main, including an isolated hello-world diagnostic

Checklist

  • Linked to an issue
  • CHANGELOG.md updated under [Unreleased]

@joshuajbouw joshuajbouw requested a review from Copilot July 14, 2026 18:02
@joshuajbouw joshuajbouw marked this pull request as ready for review July 14, 2026 18:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Introduces a validated, typed WorkspaceLayout to support a neutral per-project runtime state directory (defaulting exactly to .astrid) and threads that selection through daemon boot, kernel, capsule lifecycle/discovery, hooks, gateway trust checks, WIT GC, and readiness metadata—while preserving existing public entry points via default-layout wrappers.

Changes:

  • Add astrid_core::dirs::WorkspaceLayout (with validation) plus a stable workspace-selection fingerprint used for daemon/CLI coherency.
  • Propagate workspace layout (and explicit workspace roots where needed) across kernel boot, discovery/install/remove/update paths, hooks discovery, gateway trusted source verification, and WIT GC.
  • Publish atomic readiness metadata bound to {workspace_root, layout} and reject CLI connections to daemons serving a different selection; document behavior in CHANGELOG.md.

Reviewed changes

Copilot reviewed 50 out of 51 changed files in this pull request and generated no comments.

Show a summary per file
File Description
crates/astrid-kernel/src/socket.rs Writes atomic readiness metadata including workspace selection fingerprint.
crates/astrid-kernel/src/lib.rs Stores and threads WorkspaceLayout through kernel boot and discovery/config wiring with default wrappers.
crates/astrid-kernel/src/kernel_router/mod.rs Uses injected workspace layout for capsule discovery in router inventory.
crates/astrid-kernel/src/kernel_router/install.rs Installs capsules with explicit workspace root/layout in blocking install paths.
crates/astrid-hooks/src/discovery.rs Discovers/saves workspace hooks under the selected state directory (with layout-aware helpers).
crates/astrid-gateway/src/routes/sessions.rs Routes session endpoints using workspace context to scope trusted capsule source verification.
crates/astrid-gateway/src/routes/models.rs Threads workspace context through registry round-trips for trusted source verification.
crates/astrid-gateway/src/routes/mod.rs Adds WorkspaceContext extension and builds routers with explicit workspace inputs.
crates/astrid-gateway/src/routes/capsule_sources.rs Computes trusted capsule source IDs using explicit workspace root/layout (no implicit .astrid).
crates/astrid-gateway/src/lib.rs Runs/builds gateway with explicit workspace root/layout and preserves defaults.
crates/astrid-daemon/src/lib.rs Reads layout selection, loads config with layout, boots kernel with layout, spawns gateway with explicit workspace inputs, writes readiness metadata.
crates/astrid-core/src/dirs.rs Defines WorkspaceLayout, validation rules, layout-aware workspace paths, and workspace selection fingerprinting.
crates/astrid-core/src/dirs_tests.rs Adds regressions for layout validation, fingerprint identity, detection, and accessors.
crates/astrid-config/src/show.rs Exposes config path reporting with explicit workspace layout.
crates/astrid-config/src/merge/types.rs Updates workspace layer labeling to match selectable workspace state directory.
crates/astrid-config/src/loader.rs Loads workspace config using injected layout (and tests to ensure no dual-scan).
crates/astrid-config/src/lib.rs Adds public config loaders accepting an explicit WorkspaceLayout.
crates/astrid-config/src/defaults.toml Updates documentation comment to reflect selectable workspace config.
crates/astrid-config/Cargo.toml Adds astrid-core dependency for WorkspaceLayout.
crates/astrid-cli/src/workspace_layout.rs Adds process-wide WorkspaceLayout storage (OnceLock) for CLI-wide access.
crates/astrid-cli/src/socket_client.rs Adds connect_for_workspace helper ensuring daemon workspace selection coherency.
crates/astrid-cli/src/main.rs Initializes workspace layout once from CLI parsing.
crates/astrid-cli/src/commands/wit.rs Scopes WIT GC mark collection to selected workspace root/layout (no dual-scan).
crates/astrid-cli/src/commands/mcp/watch.rs Connects MCP watch uplink via workspace-aware daemon validation.
crates/astrid-cli/src/commands/mcp/session_guard.rs Connects MCP guard uplink via workspace-aware daemon validation.
crates/astrid-cli/src/commands/mcp/mod.rs Connects MCP serve uplink via workspace-aware daemon validation.
crates/astrid-cli/src/commands/init.rs Creates workspace dir using injected layout rather than hard-coded .astrid.
crates/astrid-cli/src/commands/headless.rs Connects headless/snapshot flows using workspace-aware daemon validation.
crates/astrid-cli/src/commands/daemon.rs Propagates workspace layout to spawned daemons and validates readiness metadata matches selection.
crates/astrid-cli/src/commands/config.rs Loads/prints config using injected workspace layout.
crates/astrid-cli/src/commands/capsule/remove.rs Resolves removal targets using injected workspace layout.
crates/astrid-cli/src/commands/capsule/meta.rs Re-exports layout-aware capsule meta scanning helpers.
crates/astrid-cli/src/commands/capsule/live_load.rs Avoids live reload/unload against mismatched daemon workspace selection.
crates/astrid-cli/src/commands/capsule/list.rs Lists installed capsules using layout-aware scan.
crates/astrid-cli/src/commands/capsule/install.rs Installs/unpacks and resolves targets using injected workspace layout.
crates/astrid-cli/src/commands/capsule/install_update.rs Updates capsules without mixing user/workspace scopes and uses layout-aware scanning/target resolution.
crates/astrid-cli/src/commands/capsule/deps.rs Builds dependency view from layout-aware installed capsule scan.
crates/astrid-cli/src/commands/capsule_verb.rs Connects to daemon for capsule verb registry/execution via workspace-aware validation.
crates/astrid-cli/src/cli.rs Adds global --workspace-state-dir / ASTRID_WORKSPACE_STATE_DIR typed option and tests.
crates/astrid-cli/src/bootstrap.rs Loads config and connects to daemon using injected workspace layout for interactive flows.
crates/astrid-capsule/src/discovery.rs Discovers manifests in an explicit workspace root/layout (no implicit .astrid).
crates/astrid-capsule-install/src/wit.rs Updates docs to reflect workspace installs under selected project state dir.
crates/astrid-capsule-install/src/paths.rs Resolves install targets using explicit workspace root/layout; adds tests.
crates/astrid-capsule-install/src/meta.rs Scans installed capsules using explicit workspace root/layout; adds tests.
crates/astrid-capsule-install/src/manifest_check.rs Checks imports/exports using explicit workspace root/layout (no implicit scan).
crates/astrid-capsule-install/src/local.rs Installs from local path using explicit workspace root/layout and layout-aware checks/paths.
crates/astrid-capsule-install/src/lib.rs Re-exports new layout-aware install/discovery APIs.
crates/astrid-capsule-install/src/contracts.rs Updates comments to reflect “no project state” reads on daemon fail-closed path.
crates/astrid-capsule-install/src/archive.rs Unpacks/installs using explicit workspace root/layout and layout-aware local install.
CHANGELOG.md Documents new workspace layout selection and coherency behavior under [Unreleased].
Cargo.lock Records astrid-config’s new dependency on astrid-core.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated 1 comment.

Comment thread crates/astrid-kernel/src/socket.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated 1 comment.

Comment thread crates/astrid-cli/src/socket_client.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

@joshuajbouw joshuajbouw force-pushed the agent/neutral-workspace-layout branch from b802249 to 225b2da Compare July 15, 2026 02:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 57 out of 58 changed files in this pull request and generated 1 comment.

Comment thread crates/astrid-cli/src/bootstrap.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 58 out of 59 changed files in this pull request and generated no new comments.

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.

Inject a neutral per-project workspace layout

2 participants