Skip to content

Commit a2304d7

Browse files
Merge branch 'main' into fix/10085-config-get-doc-example
2 parents b20fdb2 + 645b459 commit a2304d7

110 files changed

Lines changed: 2797 additions & 1779 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/candidate-compatibility.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ jobs:
185185
exec > >(tee "candidate-lane-${LANE}.log") 2>&1
186186
[[ "$LANE" == installer ]] || { echo "::error::untrusted lane id: $LANE"; exit 1; }
187187
npx vitest run --project installer-integration \
188-
test/install-openshell-version-check.test.ts \
188+
test/installer-integration/install-openshell-version-check.test.ts \
189189
--testNamePattern "validates the receipt-bound candidate through the installer path"
190190
base_path="${PATH#*:}"
191191
env \

.github/workflows/e2e.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ jobs:
137137
if: ${{ steps.publication_mode.outputs.required == '1' || steps.publication_mode.outputs.reuse == '1' }}
138138
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
139139
with:
140-
ref: ${{ inputs.checkout_sha || github.sha }}
140+
ref: ${{ inputs.workflow_sha || github.workflow_sha }}
141141
fetch-depth: 0
142142
persist-credentials: false
143143

@@ -2708,6 +2708,7 @@ jobs:
27082708
include: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
27092709
env:
27102710
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live
2711+
E2E_MANAGED_IMAGE_REVISION: ${{ needs.generate-matrix.outputs.managed_image_catalog == '' && needs.base-image-publication.outputs.managed_image_revision || '' }}
27112712
NEMOCLAW_LANGCHAIN_DEEPAGENTS_CODE_SANDBOX_BASE_IMAGE_REF: ${{ needs.base-image-publication.outputs.dcode_base_ref }}
27122713
NEMOCLAW_CLI_BIN: ${{ github.workspace }}/bin/nemoclaw.js
27132714
NEMOCLAW_RUN_LIVE_E2E: "1"
@@ -5368,7 +5369,7 @@ jobs:
53685369
path: ${{ runner.temp }}/e2e-artifacts/live/jetson-nvmap-gpu/
53695370

53705371
cloud-onboard:
5371-
needs: generate-matrix
5372+
needs: [base-image-publication, generate-matrix]
53725373
if: ${{ contains(fromJSON(needs.generate-matrix.outputs.selected_jobs), 'cloud-onboard') }}
53735374
runs-on: ubuntu-latest
53745375
timeout-minutes: 70
@@ -5379,6 +5380,7 @@ jobs:
53795380
E2E_OBSERVABLE_OUTCOME: "Public install onboarding hosted inference and security checks succeed"
53805381
E2E_ENVIRONMENT_OR_INFERENCE_ENDPOINT: "Ubuntu; NVIDIA hosted inference"
53815382
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/cloud-onboard
5383+
E2E_MANAGED_IMAGE_REVISION: ${{ needs.generate-matrix.outputs.managed_image_catalog == '' && needs.base-image-publication.outputs.managed_image_revision || '' }}
53825384
NEMOCLAW_CLI_BIN: ${{ github.workspace }}/bin/nemoclaw.js
53835385
NEMOCLAW_RUN_LIVE_E2E: "1"
53845386
NEMOCLAW_E2E_USE_HOSTED_INFERENCE: "1"

.github/workflows/platform-vitest-main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
npx vitest run --project integration test/platform.test.ts
7979
npx vitest run --project installer-integration \
8080
--testTimeout 30000 \
81-
test/install-preflight.test.ts
81+
test/installer-integration/install-preflight.test.ts
8282
8383
macos-vitest:
8484
name: macOS compatibility (${{ matrix.shard }}/4)

.github/workflows/pr-self-hosted.yaml

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ concurrency:
3030
jobs:
3131
select-llama-cpp-generic-gpu:
3232
runs-on: ubuntu-latest
33-
timeout-minutes: 5
33+
timeout-minutes: 55
34+
permissions:
35+
actions: read
36+
contents: read
3437
outputs:
38+
base_sha: ${{ steps.changed.outputs.base_sha }}
39+
managed_image_revision: ${{ steps.publication.outputs.head_sha }}
3540
selected: ${{ steps.changed.outputs.selected }}
3641
steps:
3742
- id: changed
@@ -48,6 +53,7 @@ jobs:
4853
pr_number="${BASH_REMATCH[1]}"
4954
pr_json="$(gh api "repos/$GITHUB_REPOSITORY/pulls/$pr_number")"
5055
head_sha="$(jq -er '.head.sha | select(test("^[a-f0-9]{40}$"))' <<<"$pr_json")"
56+
base_sha="$(jq -er '.base.sha | select(test("^[a-f0-9]{40}$"))' <<<"$pr_json")"
5157
[[ "$head_sha" == "$GITHUB_SHA" ]] || {
5258
echo "::error::Copied PR branch SHA does not match the current PR head" >&2
5359
exit 1
@@ -79,7 +85,42 @@ jobs:
7985
else
8086
selected=false
8187
fi
82-
printf 'selected=%s\n' "$selected" >>"$GITHUB_OUTPUT"
88+
{
89+
printf 'base_sha=%s\n' "$base_sha"
90+
printf 'selected=%s\n' "$selected"
91+
} >>"$GITHUB_OUTPUT"
92+
93+
- name: Check out trusted publication gate
94+
if: ${{ steps.changed.outputs.selected == 'true' }}
95+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
96+
with:
97+
fetch-depth: 0
98+
persist-credentials: false
99+
ref: ${{ steps.changed.outputs.base_sha }}
100+
101+
- name: Set up Node for publication verification
102+
if: ${{ steps.changed.outputs.selected == 'true' }}
103+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
104+
with:
105+
node-version: 22
106+
107+
- name: Install trusted publication gate dependencies
108+
if: ${{ steps.changed.outputs.selected == 'true' }}
109+
run: npm ci --ignore-scripts --no-audit --no-fund
110+
111+
- id: publication
112+
name: Verify applicable base-image publication
113+
if: ${{ steps.changed.outputs.selected == 'true' }}
114+
env:
115+
EXPECTED_SHA: ${{ steps.changed.outputs.base_sha }}
116+
GITHUB_TOKEN: ${{ github.token }}
117+
REQUIRE_MANAGED_IMAGE_PUBLICATION: "1"
118+
shell: bash
119+
run: |
120+
set -euo pipefail
121+
export GITHUB_REF=refs/heads/main
122+
export GITHUB_SHA="$EXPECTED_SHA"
123+
node --experimental-strip-types --no-warnings tools/e2e/base-image-publication.mts --wait-seconds 3000 --poll-seconds 30
83124
84125
llama-cpp-generic-gpu:
85126
name: llama.cpp on generic NVIDIA GPU
@@ -90,6 +131,7 @@ jobs:
90131
env:
91132
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/llama-cpp-generic-gpu
92133
E2E_JOB: "1"
134+
E2E_MANAGED_IMAGE_REVISION: ${{ needs.select-llama-cpp-generic-gpu.outputs.managed_image_revision }}
93135
E2E_TARGET_ID: llama-cpp-generic-gpu
94136
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
95137
NEMOCLAW_CLI_BIN: ${{ github.workspace }}/bin/nemoclaw.js

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Skills that write or review explanatory text must follow the shared [Documentati
3838
| `nemoclaw-blueprint/` | YAML | Blueprint definition and network policies |
3939
| `nemoclaw-blueprint/model-specific-setup/` | JSON | Agent-scoped model/provider compatibility registry |
4040
| `scripts/` | Bash/JS/TS | Install helpers, setup, automation, E2E tooling |
41-
| `test/` | JavaScript (ESM) | Root-level integration tests (Vitest) |
41+
| `test/` | JavaScript/TypeScript (ESM) | Integration tests and explicit execution lanes (see `test/README.md`) |
4242
| `test/e2e/` | Bash/JS/TS | End-to-end tests, target registry, and live runner (see `test/e2e/README.md`) |
4343
| `docs/` | MDX/Markdown | User-facing Fern docs and Markdown routes for AI documentation clients |
4444
| `fern/` | YAML/CSS/SVG | Fern site configuration and shared assets |
@@ -95,7 +95,7 @@ Tests are organized into disjoint Vitest projects defined in `vitest.config.ts`:
9595

9696
1. **`cli`**`src/**/*.test.ts` — CLI unit tests importing source
9797
2. **`integration`**`test/**/*.test.{js,ts}` — root integration tests importing source; excludes the explicit lanes below
98-
3. **`installer-integration`** — installer tests that spawn real `install.sh` processes
98+
3. **`installer-integration`**`test/installer-integration/**/*.test.ts`installer tests that spawn real `install.sh` processes
9999
4. **`package-contract`**`test/package-contract/**/*.test.ts` — the only non-live lane that imports compiled CLI/plugin artifacts
100100
5. **`plugin`**`nemoclaw/src/**/*.test.ts` — plugin unit tests co-located with source
101101
6. **`e2e-support`** — fast tests for the E2E fixture/support layer; this project runs in the
@@ -104,7 +104,7 @@ Tests are organized into disjoint Vitest projects defined in `vitest.config.ts`:
104104

105105
When writing tests:
106106

107-
- Root-level tests (`test/`) use ESM imports
107+
- Tests under `test/` use ESM imports and follow the directory ownership rules in `test/README.md`.
108108
- Plugin tests use TypeScript and are co-located with their source files
109109
- Import CLI source from ordinary tests. Put genuine compiled-artifact assertions under `test/package-contract/`.
110110
- Keep project globs disjoint and exhaustive; `npm run test:projects:check` compares filesystem candidates with Vitest and rejects missing, overlapping, or unexpected membership.

agents/hermes/host/tool-gateway-broker.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,16 @@ async function handleProxy(req, res, route) {
10051005
return;
10061006
}
10071007

1008+
// `redirect: "manual"` above already declines to follow a 3xx here, so
1009+
// relaying one just hands the same redirect to the sandbox client, which
1010+
// does follow it. Fail closed instead, matching the pinned inference
1011+
// forwarder in src/lib/inference/https-pin-runtime-adapter-forward.ts.
1012+
if (upstreamResp.status >= 300 && upstreamResp.status < 400) {
1013+
await upstreamResp.body?.cancel().catch(() => {});
1014+
sendText(res, 502, "Upstream redirect blocked: the broker does not follow or relay redirects.");
1015+
return;
1016+
}
1017+
10081018
const buffer = Buffer.from(await upstreamResp.arrayBuffer());
10091019
res.writeHead(upstreamResp.status, forwardResponseHeaders(upstreamResp));
10101020
res.end(buffer);

ci/source-shape-test-budget.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@
2121
"test": "returns a credential-free JSON manifest byte for byte",
2222
"category": "security"
2323
},
24-
{
25-
"file": "test/dashboard-remote-bind-lifecycle.test.ts",
26-
"test": "rejects a mutated checked-in security inventory instruction (#6024)",
27-
"category": "security"
28-
},
2924
{
3025
"file": "test/e2e/live/hermes-e2e.test.ts",
3126
"test": "hermes-e2e: install.sh onboards Hermes and proves health plus live inference",
@@ -166,11 +161,6 @@
166161
"test": "rejects $name even with a test-only matching lock digest",
167162
"category": "security"
168163
},
169-
{
170-
"file": "test/openclaw-locked-install.test.ts",
171-
"test": "rejects a same-registry tarball with a substituted package manifest",
172-
"category": "security"
173-
},
174164
{
175165
"file": "test/openclaw-locked-install.test.ts",
176166
"test": "rejects any lock byte tamper before registry metadata is consulted",

ci/test-file-size-budget.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"src/lib/inference/nim.test.ts": 2064,
77
"src/lib/onboard/preflight.test.ts": 1875,
88
"test/generate-openclaw-config.test.ts": 1907,
9-
"test/install-preflight.test.ts": 3025,
9+
"test/installer-integration/install-preflight.test.ts": 3025,
1010
"test/nemoclaw-start.test.ts": 4671,
1111
"test/onboard-messaging.test.ts": 2023,
1212
"test/onboard-selection.test.ts": 4177

docs/reference/commands.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4958,12 +4958,12 @@ Set them before running `$$nemoclaw onboard`.
49584958
| `NEMOCLAW_TRUSTED_PRIVATE_HOSTS` | comma-separated exact hostnames or IP literals | Allows operator-owned RFC1918, CGNAT, or IPv6 unique local destinations through supported inference, managed MCP, and custom-policy registration paths. Link-local metadata and other reserved ranges remain blocked; DNS resolution and exact address pinning remain active; wildcards are not supported. |
49594959
| `NEMOCLAW_TRUSTED_PRIVATE_INFERENCE_HOSTS` | comma-separated exact hostnames or IP literals | Inference-only compatibility alias. Inference onboarding combines entries from this variable and `NEMOCLAW_TRUSTED_PRIVATE_HOSTS`. |
49604960
| `NEMOCLAW_PREFERRED_API` | `completions` (currently the only honored value) | Forces the validation probe to use the `/v1/chat/completions` API path instead of the newer `/v1/responses` API. |
4961-
| `NEMOCLAW_INFERENCE_INPUTS` | comma-separated list of `text` and/or `image` | Declares model input modalities for vision-capable models. Validated strictly; unknown tokens are ignored. |
49624961
| `NEMOCLAW_OLLAMA_REQUIRE_TOOLS` | `0` to disable, anything else to keep the default | When set to `0`, skips the Ollama tool-calling capability check during local-inference onboarding. |
49634962
| `NEMOCLAW_OLLAMA_INSTALL_MODE` | `system`, `user`, or empty/unset | Pins the Linux Ollama install location. Refer to the Linux Ollama install mode details below. |
49644963
| `NEMOCLAW_PROXY_HOST` | hostname or IP | Overrides the sandbox-side outbound HTTP proxy host. Defaults to `10.200.0.1`. |
49654964
| `NEMOCLAW_PROXY_PORT` | integer port | Overrides the sandbox-side outbound HTTP proxy port. Defaults to `3128`. |
49664965
<AgentOnly variant="openclaw">
4966+
| `NEMOCLAW_INFERENCE_INPUTS` | comma-separated list of `text` and/or `image` | OpenClaw only. Declares model input modalities. Unsupported or duplicate values are rejected. |
49674967
| `NEMOCLAW_OPENCLAW_OTEL` | `1` to enable | Enables OpenClaw conversation diagnostics export through the `diagnostics-otel` plugin. Disabled by default. |
49684968
| `NEMOCLAW_OPENCLAW_OTEL_ENDPOINT` | OTLP/HTTP URL | Sets the OpenTelemetry collector endpoint for OpenClaw diagnostics. Defaults to `http://host.openshell.internal:4318` when `NEMOCLAW_OPENCLAW_OTEL=1`. |
49694969
| `NEMOCLAW_OPENCLAW_OTEL_SERVICE_NAME` | service name | Sets the OTEL `service.name` for OpenClaw gateway spans. Defaults to `openclaw-gateway`. |

internal/security-reviews/openshell-0.0.101-migration-review.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ are `a2704babbb468fd0a359bfdd9844de71095b730758541b4ca8cbab77d4018920` for linux
127127
`88300e35f153123e4dc3021c537834dd6c0a09665a4a6d3974cd285d512345c4` for linux-aarch64.
128128

129129
The correction commit has a raw SSH signature and exact contributor `Signed-off-by` trailer. Its
130-
independent exact-commit review passed all nine security categories, 90 focused trust tests, the
130+
independent exact-commit review passed every security category, 90 focused trust tests, the
131131
repository integrity checks, and type-checking. Both findings are closed with no new blocker.
132132
Because the formula asset remains mutable upstream, a replacement now causes a fail-closed
133133
availability failure instead of silently changing trusted identity. The dormant v0.0.101 sandbox

0 commit comments

Comments
 (0)