Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b0e93f2
refactor(dcode): replace Nemotron source patch with profile plugin
ericksoa Jul 8, 2026
cb57c5d
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
c999f82
test(dcode): harden profile validation boundaries
ericksoa Jul 8, 2026
e338b57
test(dcode): keep profile fixtures branchless
ericksoa Jul 8, 2026
59850e3
fix(dcode): verify profile plugin installation
ericksoa Jul 8, 2026
1563670
test(dcode): cover profile adapter edge cases
ericksoa Jul 8, 2026
9a48778
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
c9ab37e
test(dcode): reject incomplete profile dependencies
ericksoa Jul 8, 2026
c425fb4
test(dcode): harden profile import gate
ericksoa Jul 8, 2026
44fbc75
test(dcode): keep wheel fixture branchless
ericksoa Jul 8, 2026
4ad79de
test(dcode): support runner wheel tooling
ericksoa Jul 8, 2026
5ae2267
test(dcode): resolve profile review feedback
ericksoa Jul 8, 2026
3521591
test(dcode): resolve final advisor feedback
ericksoa Jul 8, 2026
4791ec5
test(dcode): clarify entry point failures
ericksoa Jul 8, 2026
08c5652
test(dcode): close import gate review gaps
ericksoa Jul 8, 2026
499fe9d
test(dcode): close final advisor gaps
ericksoa Jul 8, 2026
74750c5
test(dcode): keep profile fixture branchless
ericksoa Jul 8, 2026
3213b57
Merge origin/main into fix/dcode-nemotron-ultra-profile-plugin
ericksoa Jul 8, 2026
4c6b763
test(dcode): stay within image test budget
ericksoa Jul 8, 2026
4205201
test(dcode): split image contracts by boundary
ericksoa Jul 8, 2026
afa632f
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
5ed0ab6
test(dcode): harden split test fixtures
ericksoa Jul 8, 2026
d396018
test(dcode): preserve conditional budget
ericksoa Jul 8, 2026
424b312
test(dcode): share fixture drift guards
ericksoa Jul 8, 2026
a38fef6
fix(dcode): close advisor security findings
ericksoa Jul 8, 2026
0a54909
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
3a15d47
fix(dcode): align credential pattern parity
ericksoa Jul 8, 2026
cd20fc4
test(dcode): reject import gate marker drift
ericksoa Jul 8, 2026
6ac06c8
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
f15a7f3
docs(dcode): state import gate ARG boundary
ericksoa Jul 8, 2026
4a91b54
docs(dcode): clarify profile build boundaries
ericksoa Jul 8, 2026
ce2bd1c
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
1f31139
fix(security): complete pass redaction parity
ericksoa Jul 8, 2026
1f84f4e
test(dcode): keep gate fixture setup linear
ericksoa Jul 8, 2026
af424e7
fix(security): close password pattern bypasses
ericksoa Jul 8, 2026
90e1635
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
c7f08a1
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
bb2b138
test(security): cover password secret fingerprint
cv Jul 8, 2026
4da1018
fix(security): redact space-separated passwords
cv Jul 8, 2026
e587097
fix(security): align credential redaction boundaries
ericksoa Jul 8, 2026
e78d3ef
Merge remote-tracking branch 'origin/fix/dcode-nemotron-ultra-profile…
ericksoa Jul 8, 2026
a9608a9
fix(security): preserve managed redaction references
ericksoa Jul 8, 2026
c1fe500
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
58ed2e2
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
7baa42d
test(dcode): align redaction boundary probe
cjagwani Jul 8, 2026
1a69ee5
fix(dcode): close profile and redaction review gaps
ericksoa Jul 8, 2026
1b51e6a
Merge remote-tracking branch 'origin/fix/dcode-nemotron-ultra-profile…
ericksoa Jul 8, 2026
30917bf
test(dcode): deduplicate redaction probe boundary
ericksoa Jul 8, 2026
5b1a89d
fix(dcode): close profile security review
ericksoa Jul 8, 2026
0381d81
fix(security): fail closed on reply token values
ericksoa Jul 8, 2026
6980298
Merge remote-tracking branch 'origin/fix/dcode-nemotron-ultra-profile…
ericksoa Jul 8, 2026
e46b3da
test(dcode): deduplicate reply token vectors
cjagwani Jul 8, 2026
ed4fada
test(e2e): preserve reply correlation markers
ericksoa Jul 8, 2026
63d9907
Merge remote-tracking branch 'origin/fix/dcode-nemotron-ultra-profile…
ericksoa Jul 8, 2026
39bfc83
test(e2e): cover reply marker redaction path
ericksoa Jul 8, 2026
7607a95
Merge remote-tracking branch 'origin/main' into fix/dcode-nemotron-ul…
ericksoa Jul 8, 2026
79c3d85
fix(e2e): accept reviewed DCode approval arg
cjagwani Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,23 @@ jobs:
- name: Prepare E2E workspace
uses: NVIDIA/NemoClaw/.github/actions/prepare-e2e@50281ee84c4a6fc759da95ea28fc0b7d9c378a28

# invalidState: a profile plugin installed with --no-deps can import even
# when an incomplete base image omitted its required upstream packages.
# sourceBoundary: this trusted workflow scopes the repo-owned stripped-base
# build to the exact DCode target; the production Dockerfile must reject it
# at the isolated import gate before its later dependency-consistency check.
# whyNotSourceFix: dependency completeness belongs to the hash-locked base;
# resolving dependencies during local plugin install would duplicate that
# trust boundary, so the regression constructs the invalid input instead.
# regressionTest: workflow-boundary tests pin the target, script, and
# ordering; build-gate tests pin the base build and failure contract.
# removalCondition: remove only if package installation no longer uses
# --no-deps or an equivalent earlier build gate proves both imports.
- name: Verify DCode profile import gate rejects missing base dependencies
if: ${{ matrix.id == 'ubuntu-repo-cloud-langchain-deepagents-code' }}
shell: bash
run: bash scripts/check-dcode-profile-import-gate.sh

- name: Run live E2E tests
env:
NVIDIA_INFERENCE_API_KEY: ${{ secrets.NVIDIA_INFERENCE_API_KEY }}
Expand Down
33 changes: 24 additions & 9 deletions agents/langchain-deepagents-code/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ ARG BASE_IMAGE
# hadolint ignore=DL3006
FROM ${BASE_IMAGE}

USER root

RUN set -eu; \
dcode_path="$(command -v dcode 2>/dev/null || true)"; \
if [ "$dcode_path" != "/usr/local/bin/dcode" ]; then \
Expand All @@ -23,7 +25,9 @@ RUN set -eu; \
COPY agents/langchain-deepagents-code/generate-config.ts /opt/nemoclaw-deepagents-code/generate-config.ts
COPY agents/langchain-deepagents-code/managed-dcode-runtime.py /opt/nemoclaw-deepagents-code/managed-dcode-runtime.py
COPY agents/langchain-deepagents-code/patch-managed-deepagents-code.py /opt/nemoclaw-deepagents-code/patch-managed-deepagents-code.py
COPY agents/langchain-deepagents-code/patch-nemotron-ultra-profile.py /opt/nemoclaw-deepagents-code/patch-nemotron-ultra-profile.py
# SECURITY: copy only the two hash-verified plugin inputs, never the source directory.
COPY agents/langchain-deepagents-code/profile-plugin/pyproject.toml /opt/nemoclaw-deepagents-profile-plugin/
COPY agents/langchain-deepagents-code/profile-plugin/src/nemoclaw_deepagents_profile/__init__.py /opt/nemoclaw-deepagents-profile-plugin/src/nemoclaw_deepagents_profile/
COPY agents/langchain-deepagents-code/validate-nemotron-ultra-profile.py /opt/nemoclaw-deepagents-code/validate-nemotron-ultra-profile.py
COPY agents/langchain-deepagents-code/progressive_tool_disclosure.py /opt/nemoclaw-deepagents-code/progressive_tool_disclosure.py
COPY agents/langchain-deepagents-code/nemoclaw_observability.py /opt/nemoclaw-deepagents-code/nemoclaw_observability.py
Expand All @@ -33,19 +37,30 @@ COPY agents/langchain-deepagents-code/dcode-wrapper.sh /usr/local/lib/nemoclaw/d
COPY agents/langchain-deepagents-code/dcode-launcher.sh /usr/local/lib/nemoclaw/dcode-launcher.sh
COPY agents/langchain-deepagents-code/start.sh /usr/local/bin/nemoclaw-start
COPY nemoclaw-blueprint/ /opt/nemoclaw-blueprint/
# The Nemotron bridge registers managed aliases for the released SDK profile; the
# managed-runtime patch independently hardens Deep Agents Code entrypoints and
# installs the reviewed Relay observability boundary.
# Both are exact-version, fail-closed build steps validated in one layer so no
# reusable image layer can contain only one of the required managed patches.
RUN chmod 444 /opt/nemoclaw-deepagents-code/generate-config.ts /opt/nemoclaw-deepagents-code/managed-dcode-runtime.py /opt/nemoclaw-deepagents-code/patch-managed-deepagents-code.py /opt/nemoclaw-deepagents-code/patch-nemotron-ultra-profile.py /opt/nemoclaw-deepagents-code/validate-nemotron-ultra-profile.py /opt/nemoclaw-deepagents-code/progressive_tool_disclosure.py /opt/nemoclaw-deepagents-code/nemoclaw_observability.py /opt/nemoclaw-deepagents-code/validate-progressive-tool-disclosure.py /opt/nemoclaw-deepagents-code/validate-observability.py \
# The first-party profile plugin uses Deep Agents' supported entry-point hook to
# register managed aliases without modifying third-party package source. The
# managed-runtime patch independently hardens DCode entrypoints and installs the
# reviewed Relay observability boundary. Build validation keeps both exact and
# fail closed in one layer.
# invalidState: a no-deps plugin install can precede missing base dependencies.
# sourceBoundary: Dockerfile.base owns dependencies; this layer only proves them.
# whyNotSourceFix: dependency completeness is a NemoClaw image-build contract.
# regressionTest: the stripped-base gate must reach this marker, then fail import.
# removalCondition: remove when installation validates dependencies atomically.
# hadolint ignore=DL4006
RUN chmod 444 /opt/nemoclaw-deepagents-code/generate-config.ts /opt/nemoclaw-deepagents-code/managed-dcode-runtime.py /opt/nemoclaw-deepagents-code/patch-managed-deepagents-code.py /opt/nemoclaw-deepagents-code/validate-nemotron-ultra-profile.py /opt/nemoclaw-deepagents-code/progressive_tool_disclosure.py /opt/nemoclaw-deepagents-code/nemoclaw_observability.py /opt/nemoclaw-deepagents-code/validate-progressive-tool-disclosure.py /opt/nemoclaw-deepagents-code/validate-observability.py \
&& chmod 755 /usr/local/bin/nemoclaw-start /usr/local/lib/nemoclaw/dcode-wrapper.sh /usr/local/lib/nemoclaw/dcode-launcher.sh \
&& chmod -R a+rX /opt/nemoclaw-blueprint \
&& python3 /opt/nemoclaw-deepagents-code/patch-nemotron-ultra-profile.py \
&& test "$(find /opt/nemoclaw-deepagents-profile-plugin -type f -print | LC_ALL=C sort)" = "$(printf '%s\n' '/opt/nemoclaw-deepagents-profile-plugin/pyproject.toml' '/opt/nemoclaw-deepagents-profile-plugin/src/nemoclaw_deepagents_profile/__init__.py')" \
&& printf '%s %s\n' '75ff7e7a5142cad4305126ccb1b8fc756306e82d4c559ddbc624012fb54ebfc4' '/opt/nemoclaw-deepagents-profile-plugin/src/nemoclaw_deepagents_profile/__init__.py' '7ba7b77bd6f889cc861eddbe3e38fc1f4433a85b7bc2a9b516e19a19a37a7686' '/opt/nemoclaw-deepagents-profile-plugin/pyproject.toml' | sha256sum -c - \
&& /opt/venv/bin/pip3 install --no-index --no-cache-dir --no-deps --no-build-isolation /opt/nemoclaw-deepagents-profile-plugin \
&& /opt/venv/bin/python3 -I -c 'import nemoclaw_deepagents_profile; print("NEMOCLAW_DCODE_PROFILE_" + "IMPORT_GATE", flush=True); import deepagents; import deepagents_code' \
&& /opt/venv/bin/pip3 check \
&& rm -rf /opt/nemoclaw-deepagents-profile-plugin \
&& python3 /opt/nemoclaw-deepagents-code/patch-managed-deepagents-code.py \
&& install -d -m 0700 /tmp/nemoclaw-progressive-validation \
&& TMPDIR=/tmp/nemoclaw-progressive-validation python3 /opt/nemoclaw-deepagents-code/validate-progressive-tool-disclosure.py \
&& TMPDIR=/tmp/nemoclaw-progressive-validation python3 /opt/nemoclaw-deepagents-code/validate-nemotron-ultra-profile.py \
&& TMPDIR=/tmp/nemoclaw-progressive-validation /opt/venv/bin/python3 -I /opt/nemoclaw-deepagents-code/validate-nemotron-ultra-profile.py \
&& rm -rf /tmp/nemoclaw-progressive-validation \
&& /opt/venv/bin/python3 -I /opt/nemoclaw-deepagents-code/validate-observability.py \
&& rm -f /opt/nemoclaw-deepagents-code/validate-progressive-tool-disclosure.py \
Expand Down
36 changes: 15 additions & 21 deletions agents/langchain-deepagents-code/dcode-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ run_dcode() {
# raw or escaped bodies before mutable metadata can reach status output.
# * Name-context rejection fires case-insensitively when the variable name
# ends in a credential keyword (_KEY, _TOKEN, _SECRET, _PASSWORD,
# _CREDENTIAL, _PASS) and the value is at least 10 chars (mirroring
# _PASSWD, _PASS, _CREDENTIAL) and the value is at least 10 chars (mirroring
# CONTEXT_PATTERNS minimum length).
# * Managed messaging values (SLACK_BOT_TOKEN, SLACK_APP_TOKEN,
# TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN) are allowed only when the value
Expand Down Expand Up @@ -145,9 +145,11 @@ run_dcode() {
has_context_secret_shape() {
local upper
upper="$(printf '%s' "$1" | tr '[:lower:]' '[:upper:]')"
# The outer class accepts '=', ':', or whitespace; [:space:] is the nested
# POSIX character class understood by Bash's [[ string =~ regex ]] operator.
[[ "$upper" =~ (_KEY|API_KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)[=:[:space:]][\'\"]?[A-Z0-9_.+/=-]{10,} ]]
# Keep horizontal separator whitespace bounded to mirror the canonical
# lookbehind and avoid an attacker-controlled scan over arbitrarily long runs.
[[ "$upper" =~ (^|[^A-Z0-9])([A-Z0-9]{1,128}_(KEY|TOKEN|SECRET|CREDENTIAL|PASSWORD|PASSWD|PASS)|(X[-_])?API[-_]KEY|TOKEN|SECRET|CREDENTIAL|PASSWORD|PASSWD|PASS)[\'\"]?([[:blank:]]{0,32}[=:][[:blank:]]{0,32}|[[:blank:]]{1,32})[\'\"]?[^[:space:]\'\"]{10,} ]] \
|| [[ "$1" =~ (^|[^A-Za-z0-9])([A-Za-z0-9]{1,128}(Token|Secret|Credential)|[A-Za-z0-9]{0,128}([Aa]ccess|[Rr]efresh|[Cc]lient|[Bb]earer|[Aa]uth|[Aa][Pp][Ii]|[Pp]rivate|[Ss]igning|[Ss]ession|[Bb]ot|[Aa]pp|[Rr]esolved)Key|[A-Za-z0-9]{1,128}(Password|Passwd|Pass))[\'\"]?([[:blank:]]{0,32}[=:][[:blank:]]{0,32}|[[:blank:]]{1,32})[\'\"]?[^[:space:]\'\"]{10,} ]] \
|| [[ "$1" =~ (^|[^A-Za-z0-9])KEY[\'\"]?([[:blank:]]{0,32}[=:][[:blank:]]{0,32}|[[:blank:]]{1,32})[\'\"]?[^[:space:]\'\"]{10,} ]]
}

has_bearer_secret_shape() {
Expand All @@ -166,23 +168,11 @@ has_bearer_secret_shape() {

has_private_key_block_shape() {
local value="$1"
local required_separator="${2-}"
local begin_marker="-----BEGIN "
local end_marker="-----END "
case "$value" in
*"$begin_marker"*"PRIVATE KEY-----"*"$end_marker"*"PRIVATE KEY-----"*)
return 0
;;
esac
return 1
}

has_multiline_private_key_block_shape() {
local value="$1"
local begin_marker="-----BEGIN "
local end_marker="-----END "
local newline=$'\n'
case "$value" in
*"$begin_marker"*"PRIVATE KEY-----"*"$newline"*"$end_marker"*"PRIVATE KEY-----"*)
*"$begin_marker"*"PRIVATE KEY-----"*"$required_separator"*"$end_marker"*"PRIVATE KEY-----"*)
return 0
;;
esac
Expand Down Expand Up @@ -331,7 +321,7 @@ has_credential_name_context() {
local upper
upper="$(printf '%s' "$1" | tr '[:lower:]' '[:upper:]')"
case "$upper" in
KEY | API_KEY | TOKEN | SECRET | PASSWORD | PASS | CREDENTIAL)
KEY | API_KEY | TOKEN | SECRET | PASSWORD | PASSWD | PASS | CREDENTIAL)
return 0
;;
LANGSMITH_RUNS_ENDPOINTS | LANGCHAIN_RUNS_ENDPOINTS)
Expand All @@ -340,10 +330,14 @@ has_credential_name_context() {
OTEL_EXPORTER_OTLP_ENDPOINT | OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | OTEL_EXPORTER_OTLP_HEADERS | OTEL_EXPORTER_OTLP_TRACES_HEADERS)
return 0
;;
*_API_KEY | *_KEY | *_TOKEN | *_SECRET | *_PASSWORD | *_PASS | *_CREDENTIAL)
*_API_KEY | *_KEY | *_TOKEN | *_SECRET | *_PASSWORD | *_PASSWD | *_PASS | *_CREDENTIAL | *-API-KEY | *-KEY | *-TOKEN | *-SECRET | *-PASSWORD | *-PASSWD | *-PASS | *-CREDENTIAL)
return 0
;;
esac
if [[ "$1" =~ [A-Za-z0-9](Token|Secret|Credential|Password|Passwd|Pass)$ ]] \
|| [[ "$1" =~ ([Aa]ccess|[Rr]efresh|[Cc]lient|[Bb]earer|[Aa]uth|[Aa][Pp][Ii]|[Pp]rivate|[Ss]igning|[Ss]ession|[Bb]ot|[Aa]pp|[Rr]esolved)Key$ ]]; then
return 0
fi
return 1
}

Expand Down Expand Up @@ -465,7 +459,7 @@ assert_no_secret_env_file() {
# Scan the whole file before line parsing so raw multiline blocks cannot put
# their begin and end markers on different physical dotenv lines.
env_file_content="$(<"$env_file")"
if has_multiline_private_key_block_shape "$env_file_content"; then
if has_private_key_block_shape "$env_file_content" $'\n'; then
refuse_secret_env "$env_file" "private-key block"
fi
while IFS= read -r line || [ -n "$line" ]; do
Expand Down
114 changes: 89 additions & 25 deletions agents/langchain-deepagents-code/dependency-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,96 @@ NemoClaw no longer vendors or overlays that source.

- Native profile SHA-256: `c8e8dd2b0182334b54be4f46ff0c7b45fbb95dc13bd9a92c249eb47a14fa13d7`
- Unmodified built-in bootstrap SHA-256: `005a91e7fc4ca6b21220673dd9d02d6686bf63e1e4f1102d124b01f96886efcf`
- Managed-alias bootstrap SHA-256: `9d9e817143b330fd45345fcfa8276ea6fe5d6bc5a396f0438b0899a450e4744b`

The build patch verifies those official artifacts, then registers the native
profile under the two `openai:` model keys used by NemoClaw's managed
OpenAI-compatible `ChatOpenAI` route. It is atomic, idempotent, and fails closed
on version, source, bootstrap, or partial-state drift. The image build applies
the patch and runs the complete profile and dispatch validator against the
installed hash-locked wheels, while focused fixtures cover failure states.
This build-time site-packages mutation is the deliberate managed-image adapter;
the released package is never changed at runtime. The deleted source-backport
license path, `LICENSE.langchain-deepagents`, is not staged into the image, and
the image regression tests enforce that absence.
- First-party adapter: `nemoclaw-deepagents-profile==0.1.0`
- Adapter module SHA-256: `75ff7e7a5142cad4305126ccb1b8fc756306e82d4c559ddbc624012fb54ebfc4`
- Adapter project metadata SHA-256: `7ba7b77bd6f889cc861eddbe3e38fc1f4433a85b7bc2a9b516e19a19a37a7686`
- Adapter wheel license expression: `Apache-2.0`
- Adapter dependency audit result: `No known vulnerabilities found`. Its only
requirements are the exact `deepagents-code==0.1.34` and
`deepagents==0.7.0a6` entries covered by the lockfile audit command above; no
additional third-party distribution is introduced.

### Test-only legacy license fixture limitation

> **Removal condition:** Delete the test-only legacy license-table conversion in
> `test/langchain-deepagents-code-nemotron-profile-plugin.test.ts` as soon as the
> runner's system setuptools accepts PEP 639 license strings. Production never
> uses this conversion.

The adapter metadata intentionally uses the PEP 639 SPDX expression
`license = "Apache-2.0"`, supported by its pinned production build backend.
The real-wheel test substitutes the equivalent legacy table only for its
offline, no-isolation wrong-version fixture with the runner's older system
setuptools; this is a known fixture limitation, not production metadata. The
production image builds the unchanged project with lock-pinned
`setuptools==82.0.1`, and its isolated validator fails closed unless the
installed wheel exposes `License-Expression: Apache-2.0`.

The adapter is a private, first-party build-context package: NemoClaw does not
publish it to a registry or resolve it from an index. The image verifies its
reviewed source and project-metadata hashes, then builds it offline with
`--no-index --no-deps --no-build-isolation`. There is therefore no separate
published distribution for a registry audit to resolve. If that packaging
boundary ever changes, the publishing workflow must build and audit the wheel
before upload; index publication is not permitted without that release gate.

The adapter project remains recoverable from the image's `COPY` layer after the
later `RUN` removes its duplicate build tree; a failed build may likewise retain
that layer in the trusted local cache. This is accepted because the project
contains only non-secret, first-party Apache-2.0 source and metadata, and the
installed Python module necessarily ships the same source in `site-packages`.
A multi-stage build or secret mount would not make the shipped module
confidential. Revisit this boundary if an adapter build input becomes
secret-bearing or non-public.

Before local build and installation, the managed image verifies that the build
tree contains exactly the two individually copied adapter inputs, then checks
both against the module and project-metadata hashes recorded above. Extra files
cannot enter the wheel through the Docker build context. It then installs the
first-party `nemoclaw-deepagents-profile` package
without consulting an index. Its `deepagents.harness_profiles` entry
point runs after built-in profiles are registered, reads the reviewed canonical
profile through one exact-version/hash-gated private registry lookup, and uses
Deep Agents' public registration API to map it to the two exact `openai:` model
keys used by NemoClaw's managed OpenAI-compatible `ChatOpenAI` route. The
released SDK has no public profile getter or alias API. The adapter does not add
a provider-wide OpenAI profile.

The adapter verifies the exact DCode and Deep Agents versions plus the official
native-profile and bootstrap source hashes. It also binds the imported Deep
Agents package to the distribution that supplied the reviewed version.
Registration is atomic, idempotent, and rejects missing canonical, partial, or
conflicting alias state. The image validator runs under isolated Python,
verifies the installed entry-point metadata and adapter source hash before the
upstream source checks, checks both upstream files again after profile loading,
resolves the complete native middleware for both aliases, compiles a graph,
proves parser/native dispatch parity, and confirms an unrelated OpenAI model
receives no Ultra behavior. The Docker build separately imports the adapter,
Deep Agents, and DCode under isolated Python immediately after installation;
the validator then binds the installed module to its distribution and rechecks
the module hash. A DCode-only CI regression builds the current, hash-locked
`Dockerfile.base` instead of consuming a mutable registry tag, strips both
upstream distributions, and proves the production build stops at that import
gate before the later dependency-consistency check. The targeted E2E job invokes
`scripts/check-dcode-profile-import-gate.sh` with real Docker before live tests;
the fake-Docker unit suite separately pins its diagnostic failure branches.

The reviewed native-profile and bootstrap files stay byte-for-byte unchanged.
Focused fixtures cover the reviewed version/hash, missing-source,
missing-canonical, partial/conflicting, rollback, and idempotence states. The
deleted source-backport license path, `LICENSE.langchain-deepagents`, is not
staged into the image, and image regression tests enforce that absence.

Deep Agents Code `0.1.34` is the released consumer; prerelease risk is limited
to its exact `deepagents==0.7.0a6` SDK pin. That risk is accepted because the
consumer and SDK are hash locked, the dependency audit is clean, and all source,
version, middleware, graph, and dispatch checks fail closed.

The exact version and source-hash gates are also the executable lifecycle
tracker for the alias bridge: any dependency change stops the image build with
an explicit instruction to check for native managed-alias support, and requires
this review to be updated. The admin-maintainer override for this
source-of-truth decision records that the review is satisfied on the ancestor
containing this policy
([PR review](https://github.com/NVIDIA/NemoClaw/pull/6416#pullrequestreview-4649633900)).
That approval accepts this mandatory dependency-review gate as sufficient
removal accountability, so no standalone removal issue is used. When Deep
Agents natively recognizes both managed keys, the dependency review removes the
bridge instead of updating its versions or hashes.
version, middleware, graph, and dispatch contracts are enforced by the isolated
image-build validator. That validator is the fail-closed gate because Deep
Agents deliberately isolates and logs third-party plugin callback failures.

The exact version and source-hash gates remain the executable lifecycle check
for the alias adapter: any dependency change stops the image build and requires
this review to revalidate the managed adapter. Remove it instead of refreshing
its hashes only if a future reviewed dependency already provides both exact
mappings; no external contribution is required. Issue #6424 records the
NemoClaw-owned replacement of the previous installed-bootstrap mutation.
Loading
Loading