Commit ac74291
committed
fix(cli): preserve exact base resolution metadata (#9407)
<!-- markdownlint-disable MD041 -->
## Summary
Preserve Deep Agents Code base-resolution metadata when Docker reports a
different same-repository `RepoDigest` for an exact platform-digest
override. The resolver now retains the caller's immutable platform ref
through both digest selection and finalization, so the final sandbox
Dockerfile receives the required provenance label.
Exact-main failures before this fix selected the correct `linux/amd64`
platform digest, completed the lifecycle, then failed final evidence
with `Deep Agents Code sandbox image is missing base resolution
metadata`:
-
https://github.com/NVIDIA/NemoClaw/actions/runs/32101603265/job/95604176354
-
https://github.com/NVIDIA/NemoClaw/actions/runs/32102057346/job/95604587184
An exact-head qualification of the first revision reproduced the same
symptom and exposed the remaining handoff: Docker reported another
repository digest, `getRepoDigest()` adopted it, and the finalizer
independently normalized to it again. The replacement ref could not
supply the exact inspected identity, so metadata was dropped:
-
https://github.com/NVIDIA/NemoClaw/actions/runs/32105930849/job/95615528882
## Related Issue
Fixes #9386
Follow-up to #9400 and #9392
## Changes
- Preserve an exact same-repository SHA-256 override instead of
replacing it with a different digest from Docker's `RepoDigests` list.
- Prevent finalization from independently rewriting that exact override.
- Treat an exact immutable digest ref plus matching local image identity
as valid reuse/rebuild proof when Docker omits or reports another
`RepoDigest`.
- Keep existing RepoDigest normalization for Dockerfile pins, version
tags, and other non-override resolution paths.
- Continue rejecting sparse RepoDigest evidence for mutable tags and
non-exact refs.
- Add regression coverage for the live metadata-loss sequence, omitted
`RepoDigests`, malformed JSON, and later exact-ref validation.
## Type of Change
- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)
## Quality Gates
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: the exception is
limited to an exact `imageName@sha256:<64 lowercase hex>` override
already accepted by the trusted resolver. Repository equality, digest
syntax, local image ID, OS, and architecture remain required. Non-exact
refs still require matching `RepoDigests`, and Dockerfile-pin
normalization is unchanged.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:
## DGX Station Hardware Evidence
- [ ] Tested on DGX Station
- Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh`
is unchanged.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.
## Verification
- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [ ] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable — focused pre-commit, commitlint, lint,
formatting, DCO, secret scan, and growth guardrails passed. The reused
local dependency tree reports TS2883 portability errors in five
unchanged Vitest helper files; GitHub CI is the clean-tree broad gate.
- [x] Targeted behavior tests pass for the current change set — 23/23
focused resolver, metadata lifecycle, and validation tests passed with a
30-second per-test ceiling; Oxlint and added-line formatting checks
passed.
- [ ] Applicable broad gate passed — GitHub exact-head CI and two serial
Deep Agents Code live passes pending.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
---
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved handling of sandbox base images when repository digest
metadata is unavailable or differs.
* Exact SHA-256 digest references are now preserved and validated
correctly.
* Invalid non-digest references continue to be rejected.
* Image digest and ID metadata remain accurate for valid pinned
references.
* **Tests**
* Added coverage for missing, malformed, and conflicting
repository-digest metadata scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>1 parent 5a3a358 commit ac74291
5 files changed
Lines changed: 143 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | | - | |
| 200 | + | |
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
206 | | - | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
207 | 218 | | |
208 | 219 | | |
209 | 220 | | |
| |||
218 | 229 | | |
219 | 230 | | |
220 | 231 | | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
221 | 237 | | |
222 | 238 | | |
223 | 239 | | |
| |||
226 | 242 | | |
227 | 243 | | |
228 | 244 | | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
229 | 288 | | |
230 | 289 | | |
231 | 290 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| |||
147 | 148 | | |
148 | 149 | | |
149 | 150 | | |
| 151 | + | |
150 | 152 | | |
151 | 153 | | |
152 | 154 | | |
| |||
157 | 159 | | |
158 | 160 | | |
159 | 161 | | |
| 162 | + | |
160 | 163 | | |
161 | 164 | | |
162 | 165 | | |
| |||
299 | 302 | | |
300 | 303 | | |
301 | 304 | | |
302 | | - | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
303 | 310 | | |
304 | 311 | | |
305 | 312 | | |
| |||
485 | 492 | | |
486 | 493 | | |
487 | 494 | | |
| 495 | + | |
488 | 496 | | |
489 | 497 | | |
490 | 498 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
111 | 138 | | |
112 | 139 | | |
113 | 140 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
28 | 36 | | |
29 | 37 | | |
30 | 38 | | |
| |||
67 | 75 | | |
68 | 76 | | |
69 | 77 | | |
70 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
71 | 82 | | |
72 | 83 | | |
73 | 84 | | |
| |||
89 | 100 | | |
90 | 101 | | |
91 | 102 | | |
92 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
93 | 116 | | |
94 | 117 | | |
95 | 118 | | |
| |||
115 | 138 | | |
116 | 139 | | |
117 | 140 | | |
118 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
119 | 146 | | |
120 | 147 | | |
121 | 148 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
61 | 77 | | |
62 | 78 | | |
63 | 79 | | |
| |||
0 commit comments