Skip to content

feat(winds): add minimal workspace execution CLI - #37

Merged
TheHalfMoon merged 12 commits into
mainfrom
feat/003-t057-minimal-cli
Aug 17, 2026
Merged

feat(winds): add minimal workspace execution CLI#37
TheHalfMoon merged 12 commits into
mainfrom
feat/003-t057-minimal-cli

Conversation

@TheHalfMoon

@TheHalfMoon TheHalfMoon commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Spec 003 / T057

Implements only the minimal user/CLI proof surface required by T057 on top of canonical main ca4ed9ac623773a02abac9337c2463a102dbec1c.

Flat CLI surface

  • winds workspace-open — inspect/register an existing Git workspace and emit deterministic JSON
  • winds workspace-clone — clone/register through the accepted T046 backend and emit sanitized persisted remote identity
  • winds profiles — emit workspace inventory plus concrete native shell profiles; WSL discovery is reported as AVAILABLE / UNAVAILABLE / UNSUPPORTED_ON_HOST without claiming T062 support
  • winds run — execute one explicit absolute executable through the accepted T054/T055 ledger path with JSON argv and command-history enable/disable
  • winds terminal-proof — launch an exact selected native shell profile through the accepted PTY lifecycle and immediately terminate the directly owned proof session, proving launch/lifecycle persistence without adding a renderer or persistent multiplexer
  • winds execution — inspect one execution, its typed terminal/shell-command record, and ordered events as deterministic JSON

Shape

The existing hand-rolled top-level --key value parser is retained. No clap/subcommand framework or other dependency is added. New T057 behavior is isolated in src/cli_workspace.rs; src/main.rs changes only route the six flat proof commands and extend usage text.

Safety / authority

  • existing verify, promote, and recover implementations are unchanged
  • existing-workspace commands preserve the canonical repo-external WINDS_HOME boundary
  • clone CLI rejects state-root/destination overlap before creating state or clone
  • for an absolute local clone source, clone CLI also rejects a state root inside that source before creating state; file:// is rejected in this minimal CLI because proving the filesystem boundary would otherwise require new URL/path parsing machinery
  • terminal proof uses only a profile rediscovered from the current workspace inventory and the existing owned PTY lifecycle
  • terminal transcript history stays disabled/default-off in this slice
  • explicit command history may be command (best-effort redacted persisted argv) or disabled; runtime argv are unchanged
  • execution inspection binds the execution's persisted workspace to the exact --repo canonical root before returning metadata
  • execution inspection exposes persisted fact source and status source rather than synthesizing authority
  • WSL discovery output is informational only; this PR does not claim real Windows+WSL2 integration support

End-to-end proof

tests/t057_cli.rs exercises the built binary across:

workspace-open -> stable reopen identity -> profiles -> run -> execution -> cross-workspace rejection -> terminal-proof

and separately proves local-source state-root rejection before mutation, destination/state-root overlap rejection before mutation, and a successful safe clone. Test fixtures fail/skip safely when the host temporary root cannot satisfy the CLI UTF-8 prerequisite and use an ownership-checked RAII cleanup guard.

Exact-head deterministic evidence

Exact implementation head:
680d8e8894a0c6bfd1ef62a5bd373ef1f0a48d0e

Canonical base/main:
ca4ed9ac623773a02abac9337c2463a102dbec1c

  • quality #358 — PASS (Ubuntu/macOS format + Clippy + full tests, including T057 end-to-end binary tests)
  • windows-terminal #133 — PASS on official windows-latest
  • release-candidate #202 — PASS
  • SC-001 deterministic 100-cycle soak — PASS
  • Linux x86-64 release bundle/artifact — PASS
  • macOS arm64 release bundle/artifact — PASS
  • final exact-head author correctness/safety/authority review — PASS
  • final exact-head Ponytail v4.9.0 simplicity review — PASS
  • Qodo exact-head code review is bound to ca4ed9ac... -> 680d8e88... and reports Bugs (0) / Rule violations (0); prior reliability finding is resolved
  • CodeRabbit selected the exact final base/head/files but remained rate-limited, so it is not counted as independent acceptance evidence
  • all inline review threads are resolved; Cubic's local-source and panic-cleanup findings are addressed, while its remaining P3 home-resolution duplication suggestion is explicitly reconciled as non-actionable under Ponytail because existing-workspace and pre-registration clone state-root paths have materially different mutation/safety contracts

Explicit boundaries

No T058+ work. No daemon/server/socket, public IPC/runtime protocol, terminal renderer, persistent detached terminal, remote runtime, plugin/provider framework, MCP/ACP/A2A, Agent Fleet, Herdr transplant, schema migration, dependency change, or verification-authority change.

T057 exact-head acceptance gates are satisfied. Merge is permitted only with unchanged-main and expected-head guards. Do not start T058 in this PR.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@TheHalfMoon, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 4 minutes

Limit details: You’ve used all 3 included reviews currently available under your plan.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1610c076-38a2-4de4-9324-83f46ea6af1f

📥 Commits

Reviewing files that changed from the base of the PR and between ca4ed9a and 680d8e8.

📒 Files selected for processing (3)
  • src/cli_workspace.rs
  • src/main.rs
  • tests/t057_cli.rs
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/003-t057-minimal-cli

Comment @coderabbitai help to get the list of available commands.

@TheHalfMoon TheHalfMoon left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Exact-head correctness / safety / authority review — PASS for Spec 003 / T057.

Reviewed exact head 24aa673e68e87ffef1d7ab62570b14ef70c95ddb against canonical base ca4ed9ac623773a02abac9337c2463a102dbec1c and the active T057 boundary.

Findings:

  • The diff is limited to the minimal CLI router, one focused CLI implementation module, and end-to-end CLI tests. No dependency, migration, workflow, protocol, daemon, renderer, Fleet, MCP/ACP/A2A, or verification-authority change is introduced.
  • Existing verify, promote, and recover implementations are not behaviorally modified.
  • Workspace open/clone/profile operations delegate to the already accepted backend identity and validation paths rather than duplicating Git truth.
  • Clone state-root/destination overlap is rejected before state-root creation, preventing the CLI preflight from creating the requested clone destination as a side effect of an invalid configuration.
  • run uses direct executable + argv semantics and the accepted T054/T055 lifecycle; command history can be disabled and transcript persistence is not enabled by this CLI slice.
  • terminal-proof selects only a freshly rediscovered native profile, reuses the accepted owned PTY lifecycle, and terminates only the directly owned proof session. It does not claim persistent attachment, descendant ownership, or renderer/multiplexer behavior.
  • execution binds the persisted execution's workspace to the exact --repo canonical root before exposing metadata from a shared Winds state root.
  • Stored authority/source fields are surfaced rather than synthesized. WSL information is explicitly discovery-only and does not claim T062 integration support.
  • The binary-level regression test proves stable workspace identity, explicit command lifecycle, durable execution inspection, cross-workspace rejection, native terminal lifecycle proof, clone overlap refusal-before-creation, and a safe successful clone.
  • Exact-head quality #354, windows-terminal #129, release-candidate #198, SC-001 soak, and Linux/macOS release bundles all pass.

No actionable correctness, process-ownership, privacy, state-root, or verification-authority finding remains from this review. T058+ remains out of scope.

@TheHalfMoon TheHalfMoon left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Exact-head Ponytail v4.9.0 simplicity review — PASS for Spec 003 / T057.

Challenge applied to every new shape on exact head 24aa673e68e87ffef1d7ab62570b14ef70c95ddb:

  • No new dependency is justified or added; the existing hand-rolled flat --key value parser remains sufficient for this proof slice.
  • No generic CLI framework, provider abstraction, plugin layer, terminal renderer, multiplexer, daemon/socket/API, remote runtime, or Agent Fleet machinery is introduced.
  • Six flat proof commands map directly to six T057 needs; there is no speculative nested command taxonomy.
  • New behavior is isolated in one concrete cli_workspace module; main.rs only wires routing/usage.
  • Backend validation, lifecycle, persistence, profile discovery, clone logic, and history policy are reused instead of reimplemented.
  • The immediate terminal-proof lifecycle is deliberately smaller than an interactive terminal UI and avoids inventing persistent attachment/session infrastructure before a later specification authorizes it.
  • WSL is reported only as discovery information; no new WSL profile/launcher framework is introduced merely for CLI symmetry.
  • Manual execution JSON construction is local and concrete because persisted typed records are not a public serialization/API contract; adding a generic DTO/protocol layer would be premature.
  • End-to-end tests are intentionally binary-facing and exercise the public CLI proof rather than creating a separate test harness abstraction.

No removable dependency/module/protocol/abstraction or speculative future-facing machinery was found. The implementation is small relative to the backend it exposes and remains inside T057.

@TheHalfMoon TheHalfMoon left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Independent-review gate handoff: deterministic exact-head gates and both author review checkpoints are complete on 24aa673e68e87ffef1d7ab62570b14ef70c95ddb. PR remains Draft. Independent review must evaluate this exact head; older-head summaries are not acceptance evidence.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Please perform the independent acceptance review on exact head 24aa673e68e87ffef1d7ab62570b14ef70c95ddb against canonical base ca4ed9ac623773a02abac9337c2463a102dbec1c and active Spec 003 / T057 only. Deterministic exact-head gates and author correctness/safety + Ponytail reviews are complete. PR intentionally remains Draft; do not infer T058+, daemon/protocol, renderer, persistent terminal, remote, plugin, or Agent Fleet scope.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

@TheHalfMoon I will perform the independent acceptance review against the specified exact head, canonical base, and Spec 003 / T057 scope only. I will not assess excluded T058+ scope. The PR will remain Draft.


🧠 Learnings used
Learnt from: CR
Repo: TheHalfMoon/Winds PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-16T04:36:23.042Z
Learning: 4. Run deterministic checks before requesting review.

Learnt from: CR
Repo: TheHalfMoon/Winds PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-16T04:36:23.042Z
Learning: 5. Run a correctness/safety review.

Learnt from: CR
Repo: TheHalfMoon/Winds PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-16T04:36:23.043Z
Learning: For 0.1 do not introduce a daemon, IPC/public runtime protocol, terminal emulator, generic runtime abstraction, Graphify/code graph, Jujutsu dependency, plugin system, MCP/A2A, port broker, service orchestration, broad sandbox framework, or AI reviewer in product code unless the active spec is explicitly amended first.
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@TheHalfMoon
TheHalfMoon marked this pull request as ready for review August 17, 2026 04:13

Copy link
Copy Markdown
Owner Author

/review

Exact-head independent acceptance scope: review 24aa673e68e87ffef1d7ab62570b14ef70c95ddb against base ca4ed9ac623773a02abac9337c2463a102dbec1c and active Spec 003 / T057. Focus on correctness, safety, workspace/process ownership, privacy, deterministic JSON truth, active-spec compliance, and unnecessary complexity. Do not infer or require T058+, daemon/server/socket/public protocol, terminal renderer, persistent detached terminals, remote runtime, plugin/MCP/ACP/A2A, Agent Fleet, or Herdr scope.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

feat(winds): minimal workspace & execution CLI surface for T057

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Add six flat CLI commands for workspace, profiles, execution, and terminal proof JSON output.
• Reuse canonical workspace/clone/inventory backends with safety guards and repo binding.
• Add end-to-end integration tests covering open→profiles→run→execution→terminal and clone overlap
 rejection.
Diagram

graph TD
  A["winds CLI (main.rs)"] --> B["T057 dispatcher (cli_workspace.rs)"] --> C["Workspace ops (open/clone/inventory)"]
  B --> D[("Store")] --> E["Execution backends (command/terminal)"] --> F["Deterministic JSON output"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Adopt clap (subcommands + typed args)
  • ➕ Removes hand-rolled flag parsing and reduces validation boilerplate
  • ➕ Improves help/usage output and error messages consistently
  • ➖ Introduces a new dependency and a larger diff for a minimal proof slice
  • ➖ May push the CLI shape away from the intentionally flat T057 surface
2. Central command registry + shared flag schema
  • ➕ Keeps no new dependencies while reducing repetitive allowed-flag checks
  • ➕ Makes it easier to add new flat commands without growing main.rs
  • ➖ Adds an internal framework that may be premature for the minimal slice
  • ➖ Still requires careful schema/versioning as commands evolve
3. Expose library API first; keep CLI as thin wrapper
  • ➕ Encourages reuse from tests and future higher-level tools
  • ➕ Keeps JSON snapshot logic in one place (library)
  • ➖ Requires more refactoring/packaging work now
  • ➖ May expand scope beyond T057’s “minimal proof surface” goal

Recommendation: The PR’s approach (isolating T057 in cli_workspace.rs, reusing canonical backends, and avoiding new deps) is appropriate for a minimal proof surface. If this CLI is expected to grow beyond proof commands, consider migrating to clap or introducing a small internal command/flag schema to keep validation and usage text maintainable.

Files changed (3) +657 / -3

Enhancement (2) +404 / -3
cli_workspace.rsImplement T057 flat CLI commands with JSON snapshots and safety guards +398/-0

Implement T057 flat CLI commands with JSON snapshots and safety guards

• Adds a dedicated dispatcher implementing workspace-open/clone/profiles/run/terminal-proof/execution. Reuses canonical workspace and execution backends, enforces allowed flags, validates clone destination vs state-root overlap, binds execution inspection to the provided repo, and emits deterministic pretty JSON (including typed terminal/shell-command records and ordered events). Includes unit tests for args parsing, history policy, and terminal size validation.

src/cli_workspace.rs

main.rsRoute new flat CLI commands and extend usage text +6/-3

Route new flat CLI commands and extend usage text

• Adds the cli_workspace module and routes the six T057 commands through its dispatcher while keeping existing verify/promote/recover unchanged. Updates usage text to document the new command surfaces and clarifies allow(dead_code) reasons for backend modules.

src/main.rs

Tests (1) +253 / -0
t057_cli.rsEnd-to-end integration tests for T057 CLI proof flow +253/-0

End-to-end integration tests for T057 CLI proof flow

• Introduces integration tests that run the built winds binary to prove workspace-open identity stability, profile discovery, explicit command execution with history disabled, execution inspection with ordered events, cross-workspace rejection, terminal-proof lifecycle termination, and clone state-root overlap rejection before destination creation.

tests/t057_cli.rs

@qodo-code-review

qodo-code-review Bot commented Aug 17, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Local .git remote bypass 🐞 Bug ⛨ Security ⭐ New
Description
require_clone_state_external_to_local_remote only enforces Repo::require_external_state_path
when Repo::open(remote) succeeds; for local remotes that are Git dirs (e.g.,
/path/worktree/.git), Repo::open can fail and the stronger “outside checkout and git dir” guard
is skipped. This can allow --home to be placed inside the source checkout even though other flows
explicitly forbid writing Winds state under a repo’s root/common-dir.
Code

src/cli_workspace.rs[R365-367]

+    if let Ok(repo) = Repo::open(&canonical_remote) {
+        repo.require_external_state_path(state_root)?;
+    }
Relevance

●●● Strong

Accepted precedent to enforce state-root outside clone source/checkout; bypass via Repo::open
failure likely fixed.

PR-#37
PR-#1

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The clone CLI only applies require_external_state_path when Repo::open succeeds, but
Repo::open depends on git rev-parse --show-toplevel (worktree requirement). When that open
fails, the code does not reject state roots inside the source checkout; this bypasses the same
invariant enforced elsewhere by Repo::require_external_state_path.

src/cli_workspace.rs[344-368]
src/git.rs[96-105]
src/git.rs[112-118]
PR-#1

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`require_clone_state_external_to_local_remote` conditionally calls `Repo::open(&canonical_remote)` and silently skips `repo.require_external_state_path(state_root)` when the remote path is not a worktree root (e.g., a worktree’s `.git` directory). That leaves only the weaker `state_root.starts_with(canonical_remote)` check, which does not prevent state roots inside the enclosing checkout.

## Issue Context
The canonical invariant is enforced by `Repo::require_external_state_path` (state root must not be under repo root or git common dir). The clone CLI should preserve that invariant for local remotes, including when the local remote path is a Git directory rather than the worktree root.

## Fix Focus Areas
- src/cli_workspace.rs[344-369]
- src/git.rs[96-118]

## Suggested approach
- Keep the current `state_root.starts_with(canonical_remote)` guard.
- If `Repo::open(&canonical_remote)` fails and `canonical_remote.file_name() == Some(OsStr::new(".git"))`, additionally treat `canonical_remote.parent()` as the candidate worktree root and enforce `Repo::open(parent)?.require_external_state_path(state_root)`.
- Alternatively, add a helper that can derive the worktree root/common dir from either a worktree path or a git-dir path and always apply `require_external_state_path` when the remote is local.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Temp dir failures skip tests 🐞 Bug ☼ Reliability ⭐ New
Description
The integration tests early-return when TestTempDir::new(...) returns None, so temp-dir
creation/canonicalization failures (including rare name collisions) can silently skip these tests
and still pass CI. This reduces test coverage and can mask regressions in the CLI surface the tests
are meant to prove.
Code

tests/t057_cli.rs[R10-12]

+    let Some(temp) = TestTempDir::new("winds-t057-cli") else {
+        return;
+    };
Relevance

●●● Strong

They’ve accepted hardening temp dir creation to avoid silent collision/skip; early-return skip
likely rejected.

PR-#3
PR-#37

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both tests return immediately when TestTempDir::new fails, and TestTempDir::new converts
create_dir/canonicalize failures into None, so failures (including collisions) can skip the test
suite. This matches a previously accepted pattern to avoid non-exclusive temp-dir creation and
collisions.

tests/t057_cli.rs[10-13]
tests/t057_cli.rs[262-285]
PR-#3

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`t057_cli` tests can silently skip by returning early when temp dir setup fails (including rare `AlreadyExists` collisions), causing CI to pass without executing assertions.

## Issue Context
`TestTempDir::new` returns `Option<Self>` and callers do `else { return; }`. The helper also does not retry on `fs::create_dir` name collisions.

## Fix Focus Areas
- tests/t057_cli.rs[10-13]
- tests/t057_cli.rs[138-142]
- tests/t057_cli.rs[262-285]

## Suggested approach
- Change `TestTempDir::new` to return `Result<Self>` (or keep `Option` but `expect` in callers) so setup failures fail the test with diagnostics.
- Add a small retry loop in `TestTempDir::new` that retries on `ErrorKind::AlreadyExists` (e.g., append a per-process counter) rather than returning `None`.
- Keep the existing safety checks in `Drop`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. workspace-clone forbids file:// 📘 Rule violation ⚙ Maintainability ⭐ New
Description
The new workspace-clone path rejects file:// remotes, which is a public CLI behavior not
described in the active Spec 003 documents for cloning a Git remote. This can cause
spec/implementation drift and unexpected CLI failures for local remotes.
Code

src/cli_workspace.rs[R345-348]

+    if let Some((scheme, _)) = remote.split_once("://") {
+        if scheme.eq_ignore_ascii_case("file") {
+            return Err(
+                "T057 workspace-clone requires an absolute local path instead of file:// so Winds can prove the clone-source/state-root boundary"
Relevance

●● Moderate

Team often aligns spec+CLI, but no clear precedent on allowing vs rejecting file:// remotes.

PR-#1
PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Spec 003 describes cloning from a “Git remote” to an explicit destination and persisting a sanitized
remote identity, but does not specify that file:// remotes must be rejected. The new CLI code adds
a hard failure for the file scheme, creating an undocumented public behavior.

Rule 2716807: Disallow code implementing behavior not described in the active spec documents
src/cli_workspace.rs[345-351]
specs/003-workspace-execution-spine/spec.md[25-38]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`workspace-clone` rejects `file://` remotes, but Spec 003 only states “Given a Git remote… clone…”, without specifying a `file://` prohibition. This introduces a new public error case not mapped to the active spec.

## Issue Context
The code currently enforces this restriction to “prove the clone-source/state-root boundary”, but that requirement is not explicitly captured in Spec 003 acceptance scenarios/requirements.

## Fix Focus Areas
- src/cli_workspace.rs[345-352]
- specs/003-workspace-execution-spine/spec.md[25-38]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Non-UTF8 test panics ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new integration tests in tests/t057_cli.rs call Path::to_str().unwrap() (and similar) on
temp-dir-derived paths; on Unix, valid non-UTF-8 paths will cause these tests to panic instead of
failing gracefully. This can make CI/test runs flaky across environments/filesystems even though the
CLI itself may simply error on non-UTF-8 argv.
Code

tests/t057_cli.rs[R16-19]

+    let opened = winds(
+        &winds_home,
+        ["workspace-open", "--repo", repo.to_str().unwrap()],
+    );
Relevance

●●● Strong

PR #18 accepted removing to_str().unwrap() in tests to avoid non-UTF8 Unix path panics.

PR-#18

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added tests repeatedly unwrap UTF-8 conversions on paths derived from temp_dir() and from
canonicalize(), which can legitimately be non-UTF-8 on Unix and thus panic.

tests/t057_cli.rs[16-25]
tests/t057_cli.rs[148-157]
tests/t057_cli.rs[231-242]
PR-#18

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`tests/t057_cli.rs` uses `to_str().unwrap()` in many places to pass paths into the `winds` and `git` command invocations and to validate cleanup. On Unix, paths are not guaranteed to be valid UTF-8; these unwraps can panic and make the test suite non-portable/flaky.

## Issue Context
The binary’s CLI parsing uses `std::env::args()` (UTF-8 only), so truly non-UTF-8 argv can’t be passed to the program; however, test helpers should not panic unexpectedly when the environment’s temp dir path is non-UTF-8.

## Fix Focus Areas
- tests/t057_cli.rs[16-38]
- tests/t057_cli.rs[148-179]
- tests/t057_cli.rs[231-243]

Suggested approach (pick one):
- Make tests gracefully skip when `std::env::temp_dir().to_str().is_none()` (early return), OR
- Refactor helpers to avoid `to_str().unwrap()` by:
 - Building `Command` directly and passing `Path`/`OsStr` for arguments where possible, and
 - When a UTF-8 string is strictly required (because the CLI uses UTF-8 args), replace unwraps with `expect` messages that clearly explain the limitation, or return early/skipping to avoid opaque panics.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 12 rules
Review mode: ⚖️ Balanced: The push changes runtime clone-source/state-root validation across multiple path cases, with meaningful boundary and filesystem behavior that warrants a careful single-pass review; the test refactor is largely supporting coverage rather than dense independent logic.

Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous review results

Review updated until commit 680d8e8 ⚖️ Balanced

Results up to commit 24aa673 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Non-UTF8 test panics ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new integration tests in tests/t057_cli.rs call Path::to_str().unwrap() (and similar) on
temp-dir-derived paths; on Unix, valid non-UTF-8 paths will cause these tests to panic instead of
failing gracefully. This can make CI/test runs flaky across environments/filesystems even though the
CLI itself may simply error on non-UTF-8 argv.
Code

tests/t057_cli.rs[R16-19]

+    let opened = winds(
+        &winds_home,
+        ["workspace-open", "--repo", repo.to_str().unwrap()],
+    );
Relevance

●●● Strong

PR #18 accepted removing to_str().unwrap() in tests to avoid non-UTF8 Unix path panics.

PR-#18

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added tests repeatedly unwrap UTF-8 conversions on paths derived from temp_dir() and from
canonicalize(), which can legitimately be non-UTF-8 on Unix and thus panic.

tests/t057_cli.rs[16-25]
tests/t057_cli.rs[148-157]
tests/t057_cli.rs[231-242]
PR-#18

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`tests/t057_cli.rs` uses `to_str().unwrap()` in many places to pass paths into the `winds` and `git` command invocations and to validate cleanup. On Unix, paths are not guaranteed to be valid UTF-8; these unwraps can panic and make the test suite non-portable/flaky.

## Issue Context
The binary’s CLI parsing uses `std::env::args()` (UTF-8 only), so truly non-UTF-8 argv can’t be passed to the program; however, test helpers should not panic unexpectedly when the environment’s temp dir path is non-UTF-8.

## Fix Focus Areas
- tests/t057_cli.rs[16-38]
- tests/t057_cli.rs[148-179]
- tests/t057_cli.rs[231-243]

Suggested approach (pick one):
- Make tests gracefully skip when `std::env::temp_dir().to_str().is_none()` (early return), OR
- Refactor helpers to avoid `to_str().unwrap()` by:
 - Building `Command` directly and passing `Path`/`OsStr` for arguments where possible, and
 - When a UTF-8 string is strictly required (because the CLI uses UTF-8 args), replace unwraps with `expect` messages that clearly explain the limitation, or return early/skipping to avoid opaque panics.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread tests/t057_cli.rs Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/cli_workspace.rs
Comment thread tests/t057_cli.rs Outdated
Comment thread src/cli_workspace.rs Outdated

@TheHalfMoon TheHalfMoon left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Final exact-head correctness / safety / authority review — PASS for Spec 003 / T057.

Reviewed exact head 680d8e8894a0c6bfd1ef62a5bd373ef1f0a48d0e against canonical base ca4ed9ac623773a02abac9337c2463a102dbec1c, including the Qodo/Cubic remediation delta.

Final findings:

  • Scope remains exactly three files: the flat CLI router, one concrete T057 CLI module, and binary-facing integration tests. No dependency, migration, workflow, protocol, daemon/server/socket, renderer, remote runtime, plugin/provider, MCP/ACP/A2A, Agent Fleet, Herdr transplant, or verification-authority change was introduced.
  • Existing verify, promote, and recover behavior remains unchanged.
  • Existing-workspace operations retain the canonical Repo::require_external_state_path boundary through the existing winds_home path.
  • Clone preflight now fails before creating state when the planned state root overlaps the destination or is inside an absolute local clone source. file:// is deliberately rejected by this minimal CLI because proving its filesystem boundary would otherwise require new URL/path parsing machinery; network-style remotes remain unaffected.
  • run preserves direct executable + argv runtime semantics while respecting command-history disable; transcript persistence is not enabled by the CLI.
  • terminal-proof re-discovers and selects an exact native profile, reuses the accepted directly-owned PTY lifecycle, and terminates only that owned proof session; it does not imply persistent attachment or descendant ownership.
  • execution verifies that persisted execution workspace identity matches the exact canonical --repo root before exposing metadata from a shared state root.
  • Stored status/source/domain facts are surfaced rather than synthesized.
  • The integration tests now fail/skip safely when the host temp root cannot satisfy the CLI UTF-8 prerequisite and use an ownership-checked RAII temp guard so failed assertions do not strand test trees.
  • The tests cover stable workspace identity, profiles, explicit command lifecycle/history-disable truth, execution inspection, cross-workspace rejection, native PTY lifecycle proof, local-source state-root rejection before mutation, destination overlap rejection before mutation, and successful safe clone.
  • Exact-head quality #358, windows-terminal #133, release-candidate #202, SC-001 100-cycle soak, and Linux/macOS release bundles all pass.

No actionable correctness, process-ownership, state-root, privacy, deterministic-output, or verification-authority finding remains. T058+ remains out of scope.

@TheHalfMoon TheHalfMoon left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Final exact-head Ponytail v4.9.0 simplicity review — PASS for Spec 003 / T057.

Challenge applied to exact head 680d8e8894a0c6bfd1ef62a5bd373ef1f0a48d0e after independent-review remediation:

  • No new dependency or CLI framework was added; the existing flat --key value parser remains adequate for the six proof commands.
  • No generic provider/protocol/DTO/plugin/multiplexer/renderer/daemon/remote/Fleet abstraction was introduced.
  • The valid local-clone state-root safety gap is fixed with one concrete pre-clone boundary check rather than a generic clone/provider layer.
  • The Qodo reliability issue is fixed with a tiny test-only ownership guard, not a production tempfile abstraction or dependency.
  • Cubic's remaining P3 duplication suggestion is intentionally not implemented. Existing-workspace home resolution and pre-registration clone home resolution now have materially different mutation/safety contracts; extracting a callback/policy abstraction for only these two cases would broaden main.rs and obscure the unique pre-clone no-mutation boundary. A third authorized state-root policy would be a concrete future trigger to extract a shared primitive.
  • The CLI module remains concrete and local; backend validation, lifecycle, persistence, profile discovery, clone logic, and history policy are reused.
  • Binary-facing tests exercise the actual public proof surface and remain limited to the T057 contract.

No removable dependency/module/protocol or justified simplification remains. The final implementation stays smaller and easier to audit than the generic abstraction proposed by the remaining P3 maintainability comment.

Copy link
Copy Markdown
Owner Author

/review

Fresh exact-head acceptance review requested for Spec 003 / T057.

Review exact head 680d8e8894a0c6bfd1ef62a5bd373ef1f0a48d0e against canonical base ca4ed9ac623773a02abac9337c2463a102dbec1c only.

The prior Qodo non-UTF8 test reliability finding and Cubic local-clone state-root / panic-cleanup findings were remediated. The remaining Cubic duplication suggestion was reconciled under Ponytail as non-actionable because existing-workspace and pre-registration clone state-root resolution have materially different safety/mutation contracts.

Exact-head deterministic gates are green: quality #358, windows-terminal #133, release-candidate #202, SC-001 soak, Linux x86-64 bundle, macOS arm64 bundle. Final exact-head author correctness/safety/authority and Ponytail reviews are PASS; review threads are resolved.

Focus on correctness, safety, workspace/process ownership, privacy, deterministic JSON truth, active-spec compliance, and unnecessary complexity. Do not infer T058+, daemon/server/socket/public protocol, terminal renderer, persistent detached terminals, remote runtime, plugin/MCP/ACP/A2A, Agent Fleet, or Herdr scope.

@TheHalfMoon
TheHalfMoon merged commit 5eeb311 into main Aug 17, 2026
10 checks passed
Comment thread src/cli_workspace.rs
Comment on lines +345 to +348
if let Some((scheme, _)) = remote.split_once("://") {
if scheme.eq_ignore_ascii_case("file") {
return Err(
"T057 workspace-clone requires an absolute local path instead of file:// so Winds can prove the clone-source/state-root boundary"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. workspace-clone forbids file:// 📘 Rule violation ⚙ Maintainability

The new workspace-clone path rejects file:// remotes, which is a public CLI behavior not
described in the active Spec 003 documents for cloning a Git remote. This can cause
spec/implementation drift and unexpected CLI failures for local remotes.
Agent Prompt
## Issue description
`workspace-clone` rejects `file://` remotes, but Spec 003 only states “Given a Git remote… clone…”, without specifying a `file://` prohibition. This introduces a new public error case not mapped to the active spec.

## Issue Context
The code currently enforces this restriction to “prove the clone-source/state-root boundary”, but that requirement is not explicitly captured in Spec 003 acceptance scenarios/requirements.

## Fix Focus Areas
- src/cli_workspace.rs[345-352]
- specs/003-workspace-execution-spine/spec.md[25-38]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/cli_workspace.rs
Comment on lines +365 to +367
if let Ok(repo) = Repo::open(&canonical_remote) {
repo.require_external_state_path(state_root)?;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Local .git remote bypass 🐞 Bug ⛨ Security

require_clone_state_external_to_local_remote only enforces Repo::require_external_state_path
when Repo::open(remote) succeeds; for local remotes that are Git dirs (e.g.,
/path/worktree/.git), Repo::open can fail and the stronger “outside checkout and git dir” guard
is skipped. This can allow --home to be placed inside the source checkout even though other flows
explicitly forbid writing Winds state under a repo’s root/common-dir.
Agent Prompt
## Issue description
`require_clone_state_external_to_local_remote` conditionally calls `Repo::open(&canonical_remote)` and silently skips `repo.require_external_state_path(state_root)` when the remote path is not a worktree root (e.g., a worktree’s `.git` directory). That leaves only the weaker `state_root.starts_with(canonical_remote)` check, which does not prevent state roots inside the enclosing checkout.

## Issue Context
The canonical invariant is enforced by `Repo::require_external_state_path` (state root must not be under repo root or git common dir). The clone CLI should preserve that invariant for local remotes, including when the local remote path is a Git directory rather than the worktree root.

## Fix Focus Areas
- src/cli_workspace.rs[344-369]
- src/git.rs[96-118]

## Suggested approach
- Keep the current `state_root.starts_with(canonical_remote)` guard.
- If `Repo::open(&canonical_remote)` fails and `canonical_remote.file_name() == Some(OsStr::new(".git"))`, additionally treat `canonical_remote.parent()` as the candidate worktree root and enforce `Repo::open(parent)?.require_external_state_path(state_root)`.
- Alternatively, add a helper that can derive the worktree root/common dir from either a worktree path or a git-dir path and always apply `require_external_state_path` when the remote is local.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread tests/t057_cli.rs
Comment on lines +10 to +12
let Some(temp) = TestTempDir::new("winds-t057-cli") else {
return;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Temp dir failures skip tests 🐞 Bug ☼ Reliability

The integration tests early-return when TestTempDir::new(...) returns None, so temp-dir
creation/canonicalization failures (including rare name collisions) can silently skip these tests
and still pass CI. This reduces test coverage and can mask regressions in the CLI surface the tests
are meant to prove.
Agent Prompt
## Issue description
`t057_cli` tests can silently skip by returning early when temp dir setup fails (including rare `AlreadyExists` collisions), causing CI to pass without executing assertions.

## Issue Context
`TestTempDir::new` returns `Option<Self>` and callers do `else { return; }`. The helper also does not retry on `fs::create_dir` name collisions.

## Fix Focus Areas
- tests/t057_cli.rs[10-13]
- tests/t057_cli.rs[138-142]
- tests/t057_cli.rs[262-285]

## Suggested approach
- Change `TestTempDir::new` to return `Result<Self>` (or keep `Option` but `expect` in callers) so setup failures fail the test with diagnostics.
- Add a small retry loop in `TestTempDir::new` that retries on `ErrorKind::AlreadyExists` (e.g., append a per-process counter) rather than returning `None`.
- Keep the existing safety checks in `Drop`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 680d8e8

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