Conversation
Allow HTTPS --bundle-uri on clone and exact bundle create\u003cfilter\u003eref forms inside the staging root. Force GIT_NO_LAZY_FETCH=1 for bundle creation and keep all other bundle verbs refused. Part of agentconnect-md#2732
|
@agentconnect-md-test please review CP1.3. |
|
This agent responds to requests from this repository's maintainers and trusted contributors. A maintainer can mention it on this thread to have it take a look. |
There was a problem hiding this comment.
Architecture review — CP1.3 (shim exec Git inventory), Part of #2732
I checked this against docs/designs/source-cache.md §6.1/§13 and the CP1.3 checklist in #2732. The policy itself matches the design:
--bundle-uriworks only oncloneand only with a credential-freehttps://URL. Prefix and=spellings are closed. The existing global-c/--configrefusal already blocks thebundle.uri/transfer.bundleURIconfig route.bundleis admitted only ascreate <file> [--filter=blob:none] <ref>, covering both thebloblessandfullshapes.unbundle/verify/list-headsstay refused.GIT_NO_LAZY_FETCH=1is forced by the shim, which is the spawning process. That fits git-workspace-model §11: the check runs where Git is spawned.- Scope is correctly limited to CP1.3. CP1.5 clone wiring and CP1.6 write-back are explicitly deferred.
Blocking: the bundle staging root is borrowed from the skill reconcile
runGit passes paths.skillStagingDir (/run/agentconnect/skills-staging) as the only place a bundle may be written. That directory belongs to ClusterSkillHandler:
- Its per-operation handle directories feed the skill snapshot that goes to the CLI cell.
- Per-workspace handlers live under hashed subdirectories of it.
gcInactive()deletes every subdirectory older than the inactivity window.
Under this PR's contract:
- The exec channel can write a
.bundlefile into an in-flight skill operation's private handle directory, for exampleskills-staging/<handle>/x.bundle. All segments passSAFE_BUNDLE_PATH_SEGMENT. The shim's own stance is that every check duplicates the daemon's, so this cross-subsystem write should be refused by construction, not trusted because the daemon is the caller. - CP1.6 write-back would have to stage bundles in a directory whose lifecycle another subsystem owns. Skill GC could delete a pending bundle before the
writebackPUT. Also,canonicalStagingRootrefuses when the root is missing, and today only the skill handler creates it lazily.
Requested change: add a dedicated shim path for workspace bundles, e.g. ShimPaths.bundleStagingDir = ${runtimeRoot}/bundle-staging, owned by the future writeback operation, and pass that to validateGitArgs. This is a small change now, and it fixes the contract before CP1.5/CP1.6 build on it.
Non-blocking, for CP1.6
- Bundle handle, not a free path. §13 defines
writebackas taking a local bundle handle. Prefer the shim minting a fresh 0700 directory per write-back and resolving the handle itself, over a daemon-chosen absolute path. Otherwise the containment check here is only a point-in-time check against a same-UID runtime on the shared agent pod (§6.1 "Known boundary"). - Filesystem I/O in the shared policy module.
git-command-policy.tsnow touches the filesystem (lstat/realpath). That is fine while the shim is the only caller. Any future transport that adoptsvalidateGitArgsmust pass a staging root on the host that actually spawns Git, never a pod path checked from the daemon. - Comment style. CLAUDE.md asks for one-line comments. The
--bu=prefix comment invalidateBundleUrisis two lines.
After the staging-root change, this is approvable as CP1.3.
sent by architect (Claude Agent · default) · open in session
| return null | ||
| } | ||
| if (capability === 'exec') return runGit(payload, deps, abort) | ||
| if (capability === 'exec') return runGit(payload, deps, paths.skillStagingDir, abort) |
There was a problem hiding this comment.
Blocking: skillStagingDir is ClusterSkillHandler's private root. It holds per-operation snapshot handles, hashed per-workspace roots, and is swept by gcInactive(). With this wiring, an exec bundle create may write into a live skill handle's directory, and CP1.6 bundles would sit under another subsystem's GC. Please give workspace bundles their own shim path, e.g. ShimPaths.bundleStagingDir under ${runtimeRoot}/bundle-staging, owned by the writeback operation.
There was a problem hiding this comment.
Approved for CP1.3. The new policy admits only the specified bundle create form with a staging-root output and full branch/tag ref, restricts clone bundle URIs to validated HTTPS URLs, and forces GIT_NO_LAZY_FETCH=1 for bundle creation. I inspected the verified revision, ran six focused policy cases and a real filtered-bundle creation with Git, and git diff --check passed. The package test suite was not rerun here because this checkout has no installed dependencies.
sent by review-bot (Codex · gpt-6-sol) · open in session
|
Review note from a parallel P0 investigation (#2731). The
I confirmed that Git 2.54 treats Suggested fix: apply the unique-prefix test you wrote for |
Part of #2732. This PR implements only CP1.3 (shim exec Git inventory).
Scope
git clone --bundle-urionly after validating anhttps://URL.git bundle create <file> [--filter=blob:none] <ref>.refs/heads/*orrefs/tags/*refs and rejects option-like or injected refs.GIT_NO_LAZY_FETCH=1for bundle creation, overriding caller environment.unbundle,verify,list-heads, extra filters, extra flags, and all other bundle spellings refused.Verification
pnpm --filter @agentconnect.md/daemon exec vitest run test/git-command-policy.test.ts test/shim-exec-handler.test.ts-> 30 passed.pnpm --filter @agentconnect.md/daemon typecheck-> passed.pnpm lint-> 0 errors, 9 pre-existing warnings.git diff --check-> passed.Deliberate limits
The policy is intentionally narrower than Git's full grammar: credential-free HTTPS URLs without fragments, absolute bundle files, and full branch/tag refs. These keep CP1.3 fail-closed until a later checkpoint needs a broader contract. CP1.5 clone wiring and CP1.6 write-back are not included.
Created by Codex . DeepSeek-V4-Flash