Repository navigation
fix(forge): serve extensionless Git HTTP URLs - #319
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Suffix-aware transport routing crates/forge/src/transport.rs, docs/superpowers/specs/2026-10-22-p38-forge-design.md |
The parser accepts whitelisted Git sub-paths with or without .git and returns NotGit for /api/ paths. The route specification describes both URL forms using the same repository resolution, authorization, and CGI path. |
URL-form integration tests crates/forge/tests/e2e_git.rs |
The round-trip test clones and pushes with both URL forms. Missing-repository checks cover upload-pack and receive-pack requests with both forms. |
Maintenance writer-test shutdown
| Layer / File(s) | Summary |
|---|---|
Writer and maintenance thread join order crates/forge/tests/e2e_maintenance.rs |
The test collects writer join results, stops and joins the maintenance-pass thread, then unwraps the writer results. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Sequence Diagram(s)
sequenceDiagram
participant GitClient
participant TransportParser
participant RepositoryAuthorization
participant GitCGI
GitClient->>TransportParser: Request repository path with or without .git
TransportParser->>RepositoryAuthorization: Pass whitelisted Git path
RepositoryAuthorization->>GitCGI: Use the same repository and CGI path
Possibly related issues
- git-agentic/src-control#318: The issue reports extensionless clone requests returning 404; this change adds extensionless Git-path parsing and end-to-end coverage.
Possibly related PRs
- git-agentic/src-control#304: It introduced the Smart-HTTP transport parser that this change updates for extensionless repository paths.
- git-agentic/src-control#311: It added the maintenance runner and writer-exclusion test that this change updates to join threads in a different order.
Merge Risk: 
Minimal · up to 9d053
-
No concrete merge-blocking defect was identified in the changed behavior.
Security architecture risk: 
Minimal · up to 9d053
-
The additional URL form uses the same repository permissions and resource limits as the existing form. No material security regression was found in the reviewed change.
Retained concerns
No architecture-level concerns identified.Security review details
-
Security Blast Radius
- inferred — The reachability expansion adds URL aliases for existing repository operations, not a new repository-selection authority. Within the inspected application flow, callers remain limited to live repositories they can access; receive-pack additionally requires repository-write scope and write permission.
Trust Boundaries and Controls
- observed — Both URL forms retain decoded-name validation and the exact Git subpath whitelist. Token validation, method checks, service selection, scopes, repository visibility, and permissions run before child creation. The child receives a cleared, reconstructed environment, a repository-ID-based PATH_INFO, and REMOTE_USER only after write authorization.
Resilience and Maintainability Implications
- inferred — Using both aliases concurrently does not create separate admission or lifecycle namespaces: those controls use the resolved repository ID. The shared execution path retains live-state rechecking, disk reservations, startup-failure handling, cancellation, timeout supervision, and child cleanup. No alias-specific mutation or recovery transition was identified.
-
Pre-merge checks: 
3 · 
2
-
Failed checks: 2 warnings Passed checks: 3 passed-
Full details: Linked Issues check
-
Explanation
[
#318] Requires extensionless and.gitGit URLs to reach the same authorization and Git backend. Requires REST routing and private-repository refusals to stay unchanged. Whole-PR diff (merge base to head) ofcrates/forge/src/transport.rsshows: (1)parsereturnsNotGitfor any path starting with/api/, so REST paths stay on the API router; (2) the.gitsuffix is optional when the remainder matches a whitelisted Git sub-path (sub_of(rest)returnsSome); (3) both forms build the sameGitPath { owner, repo, sub }, so the existing authorization and CGI code receives identical data; (4) a path without suffix and with an unrecognized sub-path returnsNotGit. The whole-PR diff ofcrates/forge/tests/e2e_git.rsclones and pushes through both URL forms inpush_then_clone_round_trips. It also checks that missing and private repositories return the same 404 body (Repository not found) for both forms, for upload-pack and receive-pack. Residual note: an owner literally namedapinow routes to REST for/api/<repo>.git/...paths. The issue asks to preserve REST routing, so this is consistent with the requirement. Test execution results were not independently re-run; the assessment relies on the source diff and the test code.
-
Full details: Out of Scope Changes check
-
Explanation
Changes in
transport.rs,e2e_git.rs, and the design document (docs/superpowers/specs/2026-10-22-p38-forge-design.md) connect directly to#318. The change incrates/forge/tests/e2e_maintenance.rs(passes_beside_writers_lose_nothing) does not. It reorders writer-thread join results and the maintenance-pass thread join so that writer panics are unwrapped after the GC thread stops. It does not touch Git URL parsing, authorization, or CGI construction. The PR description also presents it as a separate fix ("Also stop the maintenance test's GC thread...") with a separate CI rationale. No linked issue covers this CI hang or the writer-failure propagation, and the PR objectives mention it only as a commit message summary. Demonstrated: the change is unrelated to the linked issue objective.Resolution
Remove the
crates/forge/tests/e2e_maintenance.rschange from this pull request. Move it to its own pull request, with its own linked issue or a clear rationale for the CI fix. Keep the transport, e2e_git, and design-document changes in this pull request.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Summary
Accept the optional
.gitsuffix for whitelisted Git requests. Normalize both forms before repository authorization and CGI construction, while keeping REST paths on the API router. Extend the real-Git round trip to clone and push through both forms and check the same missing/private repository refusals.Closes #318.
Also stop the maintenance test's GC thread before propagating a writer-thread failure. Its prior unwind order could leave CI running indefinitely and hide the actual writer failure.
Evidence
Before: the real-Git round trip failed on the extensionless clone with
repository ... not found. A repeated container probe cloned the.gitURL successfully and returned exit 128 for the same private repository without it.After: 25 Git transport tests and 137 library tests pass; formatting, affected-crate Clippy and diff checks pass.
Full recorded conformance replay: 24/24 scenarios pass, 0 failed exchanges (4 web exchanges excluded). The rebuilt pinned-toolchain container also passes the original clone probe through both URL forms.
Maintenance regression suite: 18/18 pass; affected-crate Clippy, formatting and diff checks pass.
Merge Danger
Door: two-way
Blast Radius: transport
Request classification changes. Tests cover private-repository refusals and REST fallthrough; the existing authorization and CGI owners handle both URL forms.
Summary by CodeRabbit
.gitsuffix for clone and push operations. Both URL forms access the same repository and follow the same authorization rules..git.