Conversation
- Workspace files: treat `.git` in any letter case (plus Windows
trailing-dot/space, stream and GIT~N short-name spellings) as the
repository metadata directory in request paths and listings, so
case-insensitive filesystems resolve the same refusal.
- GET /v1/diff: read the path with --literal-pathspecs (diff and the
untracked probe), so `:/`/`:(top)` magic cannot select files outside a
subdirectory workspace.
- POST /v1/git/push: `remote` must be a configured remote and may not
start with `-`.
- POST /v1/threads/{id}/jobs: resolve `cwd` against the thread workspace
and hand the manager the absolute path (it resolved relative paths
against the server's cwd); outside trust mode the cwd must stay inside
the workspace, matching the shell tool's resolve_path rule.
Tests: 5 new unit tests; targeted runtime_api::{workspace,git,jobs}
tests 29 passed / 0 failed; with fixes reverted 24 passed / 5 failed
(all five new tests). cargo fmt --check clean; no clippy findings in
touched files.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ZwqatxgVFxHvovngywnks
- Jobs: resolve `cwd` with tokio::fs so no path resolution runs on a runtime worker (the #6149 blocking-call ratchet failed on the two inline canonicalize calls). Containment is still checked on the canonical path, but the manager gets the joined spelling as before, so Windows gets no `\\?\` verbatim cwd. Doc comment and RUNTIME_API.md now say the route is stricter than the shell tool's resolve_path (no follow_symlinks, trusted roots or `~`), so a symlink leading out of the workspace is refused. - `.git` rule: one `snapshot::is_git_metadata_name` for workspace routes, file restore (validate_restore_file had its own ASCII-case-only check), snapshot delta display paths, turn-artifact display paths and the LSP semantic paths. The Windows forms live in a pure helper that takes the platform as a bool, so trailing dot/space, `:stream` and `GIT~N` are tested on every host. - Push: `push_args` builds the arguments, validates the effective remote (including the `origin` default for set_upstream) and puts `--` before the remote. Tests: 3 new/extended tests. Targeted runtime_api::{jobs,git,workspace}, snapshot::{repo,delta}, turn_artifacts and lsp filters: 132 passed / 0 failed. With the three fixes reverted: git_metadata_name, job_cwd and push_args tests fail (1 passed / 3 failed). cargo fmt --check clean; check-blocking-calls-budget, check-runtime-contract-budget and check-dead-code-budget pass; clippy reports nothing in touched files. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ZwqatxgVFxHvovngywnks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No-Issue: verified bug-hunt findings
Lane
runtime-api-workspace-git-jobs. Four leads re-verified onorigin/main(6779519); two further leads were duplicates of these. Two commits:be1e56774(the fixes) and7f84148cf(review follow-ups: blocking-call gate, one.gitrule, push wiring, job cwd wording).1. Workspace file routes match
.gitonly in lowercaseProblem:
relative_request_pathand the directory listing matched the component against.gitexactly. On case-insensitive filesystems (the macOS default, and Windows),.GIT/configor.Git/hooks/...got past that check but opened the real repository metadata. That was true for file read/write,expect.fileskeys and the stage/discard path arguments.POST /v1/threads/{id}/file-revert(SnapshotRepo::validate_restore_file) had its own, separate ASCII-case-only check.Now: one
snapshot::is_git_metadata_namematches.gitin any letter case. On Windows it also matches the trailing-dot/space,:streamandGIT~Nshort-name forms. Workspace request paths, the listing filter, file restore, snapshot-delta display paths, turn-artifact display paths and the LSP semantic paths all use it. The Windows forms are a pure helper that takes the platform as abool, so they are tested on every host.Test:
git_metadata_directory_is_refused_in_any_letter_case,listing_hides_git_metadata_directory_in_any_letter_case,git_metadata_name_covers_case_and_windows_aliases(checks.git.,.git,.git::$INDEX_ALLOCATION,GIT~1andgit~12withwindows = true, and that they are ordinary names otherwise).restore_file_if_unchanged_refuses_directories_git_metadata_and_ignored_filesadds the Windows spellings when it runs on Windows CI.Not migrated:
tools/subagent/delivery.rsandcore/authority.rskeep their own.gitchecks because those files belong to another lane.2.
GET /v1/diff?path=read the path as a pathspecProblem: the diff read and the untracked-status probe ran without
--literal-pathspecs. The writes in the same module already use it. In a workspace that is a subdirectory of a larger repository,:/other/fileor:(top)...returned diffs for tracked files outside the workspace.Now: both reads run with
--literal-pathspecs, through thefile_diff_argsbuilder.Test:
file_diff_reads_the_path_literally_inside_a_subdirectory_workspaceuses a real repo with a nested workspace.w.txtstill diffs.:/…,:(top)…and*return nothing from the sibling directory.3.
POST /v1/git/pushaccepted option-likeremotevaluesProblem: the character allow-list allowed a leading
-, so--force,--mirror,--deleteand-fwere passed togit pushas options. Paths such as../other-repowere also accepted.Now:
push_argsbuilds the arguments. The effective remote is the requested one, ororiginwhen onlyset_upstreamis given. It must appear ingit remoteand must not start with-.--comes before it.Test:
push_remote_must_be_a_configured_remote_name, pluspush_args_validate_the_effective_remote_and_end_options. The second test uses a real repo and a bare remote. It covers trim, theremotelookup and theorigindefault (400 while nooriginexists), then runs the builtpush --set-upstream -- origin mainthrough git and checks the upstream.4. Job
cwdwas checked against the thread workspace but run against the server cwdProblem:
create_thread_jobcheckedthread.workspace.join(cwd)but passed the raw string toShellManager, which resolves a relative path against the daemon's own cwd. A relative cwd therefore either failed or ran in a different directory with the same name. An absolute cwd had no containment check.Now:
resolve_job_cwdresolves the path withtokio::fs, so it never blocks a runtime worker. It checks containment on the canonical path and passes the manager the joined, absolute spelling, so Windows does not receive a\\?\verbatim cwd. Outside trust mode the cwd must stay inside the workspace. This is stricter than the shell tool'sresolve_path: the route has noworkspace_follow_symlinks, trusted external roots or~expansion, so a symlink leading out of the workspace gets 403. The doc comment anddocs/RUNTIME_API.mdstate this.Test:
job_cwd_resolves_against_the_thread_workspacecovers:Findings reviewed and not changed
Evidence
cargo test -p codewhale-tui --lib -- runtime_api::jobs::tests runtime_api::git::tests runtime_api::workspace::tests snapshot::repo::tests::{git_metadata_name,restore_file_if_unchanged_refuses,workspace_relative_path} snapshot::delta runtime_threads::turn_artifacts lsp::: 132 passed / 0 failed.git_metadata_name_covers_case_and_windows_aliases,job_cwd_resolves_against_the_thread_workspace,push_args_validate_the_effective_remote_and_end_options). The first commit's revert run was 24 passed / 5 failed.scripts/check-blocking-calls-budget.py: failed onbe1e56774(jobs.rs: path_canonicalize sites 2 > budget 0). It now passes (747 sites, within budget) with no budget raise.check-runtime-contract-budget.pyandcheck-dead-code-budget.pypass.cargo fmt --all -- --checkis clean.cargo clippy -p codewhale-tui --lib --testsreports nothing in the touched files. It does stop on 21 existingtoo_many_argumentserrors in other files.🤖 Generated with Claude Code
https://claude.ai/code/session_014ZwqatxgVFxHvovngywnks