fix(coding-agent): resolve image-generation env from trusted sources - #3309
Conversation
Yeachan-Heo
left a comment
There was a problem hiding this comment.
Verdict: APPROVE — exact head 980711793cc2825296e250bdef272722f4220c4a
External successor to closed #3273 (closed only as housekeeping/legacy-batch triage, not on a technical defect — its own review verdict was MERGE_READY). This lane independently re-verifies rather than inheriting that prior verdict at face value.
Checks performed:
- Content identity confirmed, not assumed:
git diff 2c0e0ef5<#3273 exact head> 980711793<#3309 exact head> -- packages/coding-agent/src/tools/image-gen.tsis empty — the security-relevant source is byte-identical to the version #3273's independent adversarial review already validated (own probe againstenv.ts, scenario-table trust verification,?.trim()-drop safety proof, credential-leak sweep, all confirmed sound in that review). - Rebase/force-push safety — verified via three-way merge simulation, not just
git diffagainst dev tip: this branch's merge-base withorigin/dev(1122e2ce) predates #3285/#3295'senv-file.tsextraction. A naivegit diff origin/dev pr3309misleadingly showsdirs.ts/env.ts/env-file.tschanges — that's base drift (dev moved forward), not PR content.git merge-tree $(merge-base) origin/dev pr3309confirms the actual three-way merge touches onlyimage-gen.ts+ its own test/changelog files; #3285/#3295's trust-boundary refactor is untouched by a real merge. No unrelated content introduced. - PR's own diff against its own merge-base is exactly 4 files / 152 lines, scoped entirely to image-generation env resolution — no drift, no scope creep.
- CI terminal on exact head: polled to completion — 16 SUCCESS, 5 SKIPPED (platform-gated jobs), 0 pending, 0 failing.
- Mergeability:
MERGEABLE/ clean text merge confirmed bygit merge-tree(no conflict markers). - No merge performed — read-only lane.
—
[repo owner's gaebal-gajae (clawdbot) 🦞]
88c333a to
ebe4713
Compare
Yeachan-Heo
left a comment
There was a problem hiding this comment.
Verdict: APPROVE — exact head ebe47131a8811ba528628c192fffdf852d1acd64
Rebase-only refresh of the prior exact-head review at 980711793cc2825296e250bdef272722f4220c4a (APPROVE).
Checks performed:
- Content identity confirmed, not assumed:
diff <(git show 98071179 --format= -- packages/coding-agent/src/tools/image-gen.ts packages/coding-agent/test/fixtures/image-gen-env-probe.ts packages/coding-agent/test/image-gen-env-trust.test.ts) <(git show ebe47131 --format= -- packages/coding-agent/src/tools/image-gen.ts packages/coding-agent/test/fixtures/image-gen-env-probe.ts packages/coding-agent/test/image-gen-env-trust.test.ts)is empty — the PR's own commit is byte-for-byte identical to the version the prior review validated. CHANGELOG.md is intentionally excluded from this file set: its diff context shifted because independently-mergeddevcommits inserted new entries above the same insertion point, which is expected rebase churn, not a content change to this PR's own line. - Rebase mechanics verified:
git merge-baseconfirms this PR carries the same single commit both before and after the rebase; every additional commit between the two heads is an independently-mergeddevcommit (own-PR-numbered), not new work folded into this PR. - Exact-head terminal CI: 16 success / 0 failure / 0 pending / 5 skipped (total 21). No pending/queued checks remain.
Prior technical analysis still applies verbatim to this head.
—
[repo owner's gaebal-gajae (clawdbot) 🦞]
ebe4713 to
088c892
Compare
Residual named in the Yeachan-Heo#3263 review. image-gen.ts read two things through $env, the merged view that includes the caller's cwd/.env: :1109 $env.OPENAI_BASE_URL endpoint for authenticated image requests :830/:853/:877 $env.GOOGLE_API_KEY key fallback after getEnvApiKey("google") So repository content could choose where image requests go, or supply the credential they authenticate with. The Google reads sit behind the trusted getEnvApiKey lookup, which is the same guard-defeated-by-fallback shape fixed for the provider base URLs. Both now resolve through $credentialEnv. The three Google sites share one named helper so the trusted lookup is a single code path rather than a repeated expression. The trusted getEnvApiKey("google") result still takes precedence, and shell / GJC / user-owned .env configuration is unchanged. Regression: a child process with a controlled cwd (projectEnv is parsed at module load) proves a planted .env can set neither the base URL nor the key, inherited values still apply, and a planted .env cannot override them. Reverting the two resolvers fails exactly those two cases.
088c892 to
cc94c8f
Compare
Yeachan-Heo
left a comment
There was a problem hiding this comment.
Verdict: APPROVE — exact head cc94c8f3c00613893047ba229320da3d018de5dd.
Security/trust revalidation:
- Image generation now resolves both the authenticated OpenAI image-request base URL and the
GOOGLE_API_KEYfallback through trusted-only environment resolution. The existing trustedgetEnvApiKey("google")path retains precedence. - The source and original regression coverage remain equivalent to the previously approved implementation. The semantic rebase additionally isolates the test child's HOME and agent directory, preventing a developer's trusted
~/.envor shell configuration from changing the expected default or masking project-env rejection; this failure was reproduced locally before the isolation fix. - The release note was moved from released
0.11.11toUnreleased, and the head lands directly on currentdevparenta23d599ff2834d2b5acd34716aaaa739d0c7cd9f. - Local focused trust test: 5/5 passed after the isolation fix. Coding-agent typecheck passed. Biome and diff checks passed.
- Exact-head CI is terminal with every reported check SUCCESS or SKIPPED, including the focused image-gen trust test, the existing image-gen suite, and
check:@gajae-code/coding-agent. - Mergeability is
MERGEABLE/CLEAN, and the exact remote head/base were re-pinned immediately before this verdict.
No credential values were printed or persisted during review.
— GJC security/trust review, 2026-07-28
Successor to #3273, reopened per your triage note:
#3273 could not be reopened directly — GitHub returns 422 once the head has been force-pushed — so this is a fresh PR on the same branch, rebased onto current
dev.Why it should still land
image-gen.tsreadOPENAI_BASE_URL(:1109) andGOOGLE_API_KEY(:830,:853,:877) through$env, the merged view that includes the caller'scwd/.env. So a repository could choose where authenticated image requests go, or supply the credential they authenticate with. The Google reads sit behind the trustedgetEnvApiKey("google")lookup — the same guard-defeated-by-fallback shape #3268 fixed for provider base URLs.Your review on #3273 reached MERGE_READY after independently reproducing the boundary with your own probe rather than reusing mine, and recorded that the surface closure was total. No technical blocker was raised; the later
CHANGES_REQUESTEDwas the batch-triage note quoted above.State on this head
Rebased onto current
dev(zero commits behind), suite re-run green after the rebase. Everything else is byte-identical to the head you reviewed.If the no-merge lane was a deliberate policy call for external contributions rather than housekeeping, say so and I will stop resubmitting this class rather than keep adding noise.