Skip to content

ci: auto-update release notes on push to main#1

Closed
ericksoa wants to merge 1 commit into
mainfrom
ci/auto-release-notes
Closed

ci: auto-update release notes on push to main#1
ericksoa wants to merge 1 commit into
mainfrom
ci/auto-release-notes

Conversation

@ericksoa
Copy link
Copy Markdown
Contributor

Migrated from NVIDIA/openshell-openclaw-plugin#31

Summary

  • Adds a GitHub Actions workflow that auto-updates docs/about/release-notes.md on every push to main
  • Categorizes commits into Features / Fixes / Other based on commit message prefixes (case-insensitive)
  • Filters out noise: reverts, chores, docs-only, test-only, style, and low-signal commits
  • Scopes to only new commits since last run (uses [release-notes] marker in commit message)
  • Self-loop prevention: skips if the triggering commit is from this workflow
  • Commits back with -s (DCO signed-off)

How it works

  1. On push to main, collects non-merge commits since last tag or last [release-notes] commit
  2. Categorizes by prefix: add/feat → Features, fix → Fixes, everything else → Other
  3. Inserts a dated block under the ## 0.1.0 Unreleased heading
  4. Commits and pushes the updated file

Test plan

  • Merge a commit to main and verify the workflow runs
  • Check that docs/about/release-notes.md gets a new dated section
  • Verify the workflow doesn't trigger itself (no infinite loop)
  • Verify commit messages are correctly categorized

…to main

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
ericksoa pushed a commit that referenced this pull request Mar 17, 2026
Add a preflight check that catches the #1 onboarding blocker on
Ubuntu 24.04, DGX Spark, and WSL2. When cgroup v2 is active but
Docker's daemon.json lacks "default-cgroupns-mode": "host",
onboarding now fails fast with a clear error and fix instructions
instead of failing late at gateway startup with a cryptic kubelet
error.

Closes #16
@wscurran wscurran added the CI/CD Use this label to identify issues with NemoClaw CI/CD pipeline or GitHub Actions. label Mar 20, 2026
@wscurran
Copy link
Copy Markdown
Contributor

Thanks for setting up a GitHub Actions workflow that automatically updates the release notes on pushes to the main branch, which could help keep the documentation up to date and reduce manual effort.

@wscurran wscurran added the Integration: GitHub Use this label to identify GitHub integration issues with NemoClaw. label Mar 20, 2026
@cv
Copy link
Copy Markdown
Collaborator

cv commented Mar 21, 2026

Hi @ericksoa! Thanks for putting this together — auto-updating release notes is something we've been wanting. Since this was opened, the repo has seen a lot of activity: we've added CI checks, new features, and restructured a few things. Would you mind rebasing onto the latest main when you get a chance? That way we can give it a proper review with everything up to date. Appreciate it!

@ericksoa
Copy link
Copy Markdown
Contributor Author

Superseded — release notes page now points to GitHub native releases/commits/PRs.

@ericksoa ericksoa closed this Mar 22, 2026
jessesanford pushed a commit to jessesanford/NemoClaw that referenced this pull request Mar 24, 2026
- Default model: nvidia/nemotron-3-super-120b-a12b (March 2026 release,
  12B active / 120B total MoE, 5x throughput)
- Replace meta/llama-3.3-70b-instruct with Nemotron 3 Super in the
  nvidia provider catalog (Dockerfile sed patch at build time)
- All NVIDIA models in provider: Nemotron 70B, Mistral NeMo Minitron,
  Nemotron 3 Super — no Meta/Llama
- Blueprint default profile updated to nemotron-3-super-120b-a12b
- Tracked as tech debt: NVIDIA#1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jessesanford pushed a commit to jessesanford/NemoClaw that referenced this pull request Mar 24, 2026
…IA#62)

Add a preflight check that catches the NVIDIA#1 onboarding blocker on
Ubuntu 24.04, DGX Spark, and WSL2. When cgroup v2 is active but
Docker's daemon.json lacks "default-cgroupns-mode": "host",
onboarding now fails fast with a clear error and fix instructions
instead of failing late at gateway startup with a cryptic kubelet
error.

Closes NVIDIA#16
realkim93 added a commit to realkim93/NemoClaw that referenced this pull request Apr 1, 2026
…docs

Add two behavioral tests that directly validate cv's blocker NVIDIA#1 fix:
- Healthy gateway is preserved (no destroy/forward-stop) on rerun
- Stale vs healthy vs active-unnamed states trigger correct cleanup

Also add setup-jetson entry to docs/reference/commands.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ericksoa pushed a commit that referenced this pull request Apr 7, 2026
… (#1305)

## Summary

Fixes the four issues reported in #1114 — EACCES permission errors and
missing gateway token when running inside the NemoClaw sandbox.

### Issue mapping

| # | Reported error | Fix |
|---|----------------|-----|
| 1 | `EACCES: open '/sandbox/.openclaw/openclaw.json.*.tmp'` |
`install_configure_guard` — intercepts `openclaw configure` with a clear
error and directs users to `nemoclaw onboard --resume` on the host |
| 2 | Same as #1 (different PID) | Same fix |
| 3 | `EACCES: mkdir '/sandbox/.openclaw/credentials'` | Already
resolved on main via #1519 (credentials symlink to `.openclaw-data/`) |
| 4 | No WhatsApp QR code | Consequence of #3, also resolved by #1519 |

### Root cause (issues 1 & 2)

OpenClaw's `configure` command performs atomic writes — it creates a
temp
file (`openclaw.json.PID.UUID.tmp`) in the same directory as the config.
Since `/sandbox/.openclaw/` is Landlock read-only at the kernel level,
file creation is rejected with EACCES. This is by design: the sandbox
config is intentionally immutable at runtime.

Rather than weakening Landlock (security regression), we intercept the
command in the sandbox shell and guide users to the correct host-side
workflow.

### Changes

**1. `install_configure_guard()`** — Writes a shell function wrapper to
`.bashrc`/`.profile` that intercepts `openclaw configure` and prints:
```
Error: 'openclaw configure' cannot modify config inside the sandbox.
The sandbox config is read-only (Landlock enforced) for security.

To change your configuration, exit the sandbox and run:
  nemoclaw onboard --resume

This rebuilds the sandbox with your updated settings.
```
All other `openclaw` subcommands pass through to the real binary.

**2. `export_gateway_token()`** — Reads `gateway.auth.token` from
`openclaw.json` and exports it as `OPENCLAW_GATEWAY_TOKEN`, so
interactive sessions (`openshell sandbox connect`) can authenticate
with the gateway. Persists to `.bashrc`/`.profile` using idempotent
marker blocks and cleans stale tokens on revocation.

**3. `_read_gateway_token()` helper** — Shared Python snippet used by
both `export_gateway_token` and `print_dashboard_urls` (deduplication,
uses `with open()` context manager).

All three are called in both root and non-root startup paths.

## Security properties preserved

- `/sandbox/.openclaw` remains root-owned, Landlock read-only
- `openclaw.json` remains chmod 444 (immutable)
- No new attack surface — token is read-only from existing config
- `command openclaw` bypass preserves all non-configure functionality

Fixes #1114

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…IA#1114) (NVIDIA#1305)

## Summary

Fixes the four issues reported in NVIDIA#1114 — EACCES permission errors and
missing gateway token when running inside the NemoClaw sandbox.

### Issue mapping

| # | Reported error | Fix |
|---|----------------|-----|
| 1 | `EACCES: open '/sandbox/.openclaw/openclaw.json.*.tmp'` |
`install_configure_guard` — intercepts `openclaw configure` with a clear
error and directs users to `nemoclaw onboard --resume` on the host |
| 2 | Same as NVIDIA#1 (different PID) | Same fix |
| 3 | `EACCES: mkdir '/sandbox/.openclaw/credentials'` | Already
resolved on main via NVIDIA#1519 (credentials symlink to `.openclaw-data/`) |
| 4 | No WhatsApp QR code | Consequence of NVIDIA#3, also resolved by NVIDIA#1519 |

### Root cause (issues 1 & 2)

OpenClaw's `configure` command performs atomic writes — it creates a
temp
file (`openclaw.json.PID.UUID.tmp`) in the same directory as the config.
Since `/sandbox/.openclaw/` is Landlock read-only at the kernel level,
file creation is rejected with EACCES. This is by design: the sandbox
config is intentionally immutable at runtime.

Rather than weakening Landlock (security regression), we intercept the
command in the sandbox shell and guide users to the correct host-side
workflow.

### Changes

**1. `install_configure_guard()`** — Writes a shell function wrapper to
`.bashrc`/`.profile` that intercepts `openclaw configure` and prints:
```
Error: 'openclaw configure' cannot modify config inside the sandbox.
The sandbox config is read-only (Landlock enforced) for security.

To change your configuration, exit the sandbox and run:
  nemoclaw onboard --resume

This rebuilds the sandbox with your updated settings.
```
All other `openclaw` subcommands pass through to the real binary.

**2. `export_gateway_token()`** — Reads `gateway.auth.token` from
`openclaw.json` and exports it as `OPENCLAW_GATEWAY_TOKEN`, so
interactive sessions (`openshell sandbox connect`) can authenticate
with the gateway. Persists to `.bashrc`/`.profile` using idempotent
marker blocks and cleans stale tokens on revocation.

**3. `_read_gateway_token()` helper** — Shared Python snippet used by
both `export_gateway_token` and `print_dashboard_urls` (deduplication,
uses `with open()` context manager).

All three are called in both root and non-root startup paths.

## Security properties preserved

- `/sandbox/.openclaw` remains root-owned, Landlock read-only
- `openclaw.json` remains chmod 444 (immutable)
- No new attack surface — token is read-only from existing config
- `command openclaw` bypass preserves all non-configure functionality

Fixes NVIDIA#1114

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
jyaunches referenced this pull request in jyaunches/NemoClaw Apr 14, 2026
- Guard runArgv/runArgvCapture against shell:true to prevent security
  bypass (finding #1) — throws if a caller attempts to re-enable shell
  interpretation. Added 2 tests.
- Document the intentional bash -c exception in getOllamaWarmupCommand
  explaining why it's safe (finding NVIDIA#2).
- Remove dead getOpenshellCommand() from policies.ts (finding NVIDIA#3).
- Remove unused shellQuote import from nim.ts (finding NVIDIA#4).
- Fix brittle indexOf assertion in onboard-readiness test (finding NVIDIA#5).
prekshivyas added a commit to ColinM-sys/NemoClaw that referenced this pull request Apr 16, 2026
…xercised

CodeRabbit correctly flagged that the original test swapped the lock
file on stat NVIDIA#1 which caused isProcessAlive to see a live PID and
exit early — unlinkIfInodeMatches was never called. Move the swap to
after stat NVIDIA#1 returns so the stale-cleanup branch is actually reached
and the inode comparison is tested.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas added a commit to ColinM-sys/NemoClaw that referenced this pull request Apr 16, 2026
…exercised

CodeRabbit correctly flagged that swapping on stat NVIDIA#1 caused
readFileSync to see the live PID and exit via isProcessAlive —
unlinkIfInodeMatches was never called. Move the swap to just before
stat NVIDIA#2 (inside unlinkIfInodeMatches): stat NVIDIA#1 reads the original
stale inode, readFileSync sees the dead PID, isProcessAlive returns
false, stale-cleanup runs, and stat NVIDIA#2 sees the new inode and skips
the unlink.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas added a commit to ColinM-sys/NemoClaw that referenced this pull request Apr 16, 2026
…exercised

CodeRabbit correctly flagged that swapping on stat NVIDIA#1 caused
readFileSync to see the live PID and exit via isProcessAlive —
unlinkIfInodeMatches was never called. Move the swap to just before
stat NVIDIA#2 (inside unlinkIfInodeMatches): stat NVIDIA#1 reads the original
stale inode, readFileSync sees the dead PID, isProcessAlive returns
false, stale-cleanup runs, and stat NVIDIA#2 sees the new inode and skips
the unlink.

Use write-to-temp + rename instead of unlink + recreate to guarantee
a different inode even on tmpfs/overlayfs which can reuse inodes.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
jyaunches pushed a commit that referenced this pull request Apr 20, 2026
- Remove unused getForwardList() call from getActiveSandboxSessions —
  only pgrep/ps is needed for SSH session detection (warning #1)
- Consolidate double-prompt in sandboxDestroy into single enriched
  confirmation prompt (warning #2)
- Remove noisy cleanupGatewayAfterLastSandbox forward check that would
  always fire due to dashboard forward (warning #3)
- Use word-boundary regex in parseSshProcesses to prevent false positives
  when sandbox names share prefixes (warning #4)
- Export SessionClassification as named interface (suggestion #1)
- Use cross-platform ps -axo instead of Linux-only pgrep -a for macOS
  compatibility (suggestion #2)
- Add forwardCount to SessionClassification for future consumers
- Add tests for word-boundary matching edge cases
jyaunches added a commit that referenced this pull request May 12, 2026
…ded on main

Drift from main — test-hermes-inference-switch.sh,
test-openclaw-inference-switch.sh, and test-openshell-gateway-upgrade.sh
were added to main after this branch forked. The convention lint
correctly flagged them as orphans (Risk #1: new legacy scripts with
no migration mapping).

Added placeholder entries (empty scenario + assertions) to bring the
map back in sync with the legacy surface area. Actual mappings land
with their respective migration waves.
cjagwani pushed a commit that referenced this pull request May 14, 2026
Resolve the two output threads in #3456 left after the core dead-loop fix
landed via #3459 + #3434:

Sub-bug #3 — `src/lib/onboard.ts` printed
  `nemoclaw <name> destroy --yes && nemoclaw onboard --gpu`
with a literal `<name>` placeholder, and assumed at least one sandbox
was registered. When the GPU-passthrough mismatch hit on the State B
re-run path with an empty registry (the dead-loop case), the hint was
not actionable. Replace with a registry-aware helper at
`src/lib/onboard/gpu-recovery.ts` that renders the right shape:
  - empty registry → suggest `nemoclaw uninstall && nemoclaw onboard --gpu`
  - one sandbox → suggest destroy --yes --cleanup-gateway for that name
  - multiple sandboxes → list each, only the last gets --cleanup-gateway

Sub-bug #4 — `src/lib/actions/uninstall/run-plan.ts` printed
  `Destroyed gateway 'nemoclaw' skipped`
when the openshell destroy no-op'd (gateway already gone) — the
"Destroyed … skipped" wording was self-contradictory. Extend
`runOptional` with an `onSkip` option; route the gateway destroy to
emit `Gateway 'nemoclaw' already removed or unreachable` on no-op.

Tests:
- `src/lib/onboard/gpu-recovery.test.ts` (6 tests): forbid literal
  `<name>` placeholder anywhere in the output; cover empty / single /
  multi-sandbox cases; defensive filter on whitespace names so a
  `nemoclaw  destroy` rendering can never happen.
- `src/lib/actions/uninstall/run-plan.test.ts`: assert the new
  "already removed or unreachable" wording and the absence of the
  "Destroyed gateway 'nemoclaw' skipped" string.

The core dead loop itself (sub-bugs #1, #2 and State B GPU mismatch)
is already addressed by #3459 + #3434 + #3483; #3456 will close once
this lands. See the #3456 status comment for the full mapping.

Refs #3456. Mirrors (and tightens) the approach in the closed PR #3464,
which left the literal `<name>` placeholder in tests per CodeRabbit
feedback that was never addressed.

Signed-off-by: Charan Jagwani <charjags100@gmail.com>
cv added a commit that referenced this pull request May 14, 2026
…3520)

> **Draft for visibility.** Issue-autopilot Stages 4-5 of #3456. Will
mark ready once batch self-review + CI complete.

## Summary

Closes the two remaining output threads in #3456 after the core
dead-loop fix already landed on `main` (via #3459, #3434, #3483). Full
sub-bug mapping in the [#3456 status
comment](#3456 (comment)).

- **Sub-bug #3** — `nemoclaw <name> destroy --yes` recovery hint
replaced with a registry-aware helper.
- **Sub-bug #4** — `Destroyed gateway 'nemoclaw' skipped`
self-contradictory wording replaced with `Gateway 'nemoclaw' already
removed or unreachable`.

## Acceptance criteria mapping

| Sub-bug | Resolution | Evidence |
|---|---|---|
| #1 dead loop | Already fixed on main (#3459) | out of scope |
| #2 firewall diagnostic | Already fixed on main (#3459) | out of scope
|
| **#3** literal `<name>` placeholder | **This PR** |
`src/lib/onboard/gpu-recovery.ts` + `onboard.ts:10387-10405` |
| **#4** misleading "skipped" wording | **This PR** |
`src/lib/actions/uninstall/run-plan.ts:210-228, 407-414` |
| #5 uninstall residuals | Already fixed on main (#3483) | out of scope
|

## Behavior matrix

`gpuPassthroughRecoveryLines(names)`:

| Input | Suggestion |
|---|---|
| `null` / `[]` | `nemoclaw uninstall && nemoclaw onboard --gpu` |
| one sandbox | `nemoclaw <name> destroy --yes --cleanup-gateway &&
nemoclaw onboard --gpu` |
| many sandboxes | each `destroy --yes`, only the last gets
`--cleanup-gateway` |

## Test plan

```
npm run typecheck:cli
npx vitest run src/lib/onboard/gpu-recovery.test.ts src/lib/actions/uninstall/run-plan.test.ts
```

22 tests pass (6 new + 16 existing).

## Notes for reviewers

- This is the work [#3464
attempted](#3464); that PR was
closed without merging after CodeRabbit asked for the `<name>`
placeholder to be forbidden in tests via negative assertion. This PR
adopts that refinement.
- `runOptional` extension is backwards-compatible — existing callers
without `onSkip` get the original wording.

Closes #3456 once merged.

---------

Signed-off-by: Charan Jagwani <charjags100@gmail.com>
Co-authored-by: Charan Jagwani <charjags100@gmail.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
tantodefi added a commit to tantodefi/NemoClaw that referenced this pull request May 14, 2026
Two streaming bugs that combined to hang every open-webui chat with the
chad model for ~60s per turn until the frontend's read timeout:

1. The handler advertised `Connection: keep-alive` for the SSE response.
   Open-webui's frontend held the TCP connection open waiting for more
   chat-completion chunks (legitimate for normal HTTP, wrong for an SSE
   stream that's done after the [DONE] sentinel). Switched to
   `Connection: close` and explicit `self.close_connection = True` so
   BaseHTTPRequestHandler tears down the socket the moment the handler
   returns.

2. No flush between SSE events. Python's BufferedWriter on
   BaseHTTPRequestHandler buffers writes until the socket closes — which,
   combined with bug NVIDIA#1, meant the entire response landed at once *after*
   the connection should have already been done. Added explicit
   self.wfile.flush() calls after each event so chunks arrive
   incrementally.

Symptom seen: open-webui showed a 2/2 swipe carousel where the actual
chat reply briefly appeared and then got replaced; the "thinking bubble"
animation kept playing after the response finished. The 2/2 was
secondary — open-webui's auto-generated title (now routed to a separate
fast NVIDIA endpoint via the task-model config) was racing with the chat
reply because both streams were still "open" from open-webui's view.

Verified live: streaming round-trip is now 12s (was hitting the 60s
wall every time). Non-streaming path unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
jyaunches added a commit that referenced this pull request May 28, 2026
Run 26550936453 surfaced two more real bugs after Phase 6 wiring went
live. Both fixed inside the spec's prescribed layers; nothing leaks
into workflow YAML or clients.

1. dispatch-action.sh called e2e_context_init unconditionally before
   sourcing the install/onboard dispatcher. e2e_context_init opens
   context.env with `: > ctx`, which truncated the file the
   ScenarioRunner had just seeded. All runtime assertions then failed
   with 'e2e context: missing required key(s): E2E_SCENARIO ...'.
   Fix: dispatch-action.sh no longer calls e2e_context_init. The TS
   framework owns context.env initialization; workers may still extend
   it via e2e_context_set.

2. The legacy onboarding.preflight.passed assertion expects an
   onboard.log file at ${E2E_CONTEXT_DIR}/onboard.log. The old bash
   runner used to redirect onboarding output there; the typed
   orchestrator captured it under .e2e/actions/<action-id>.log. Fix:
   add optional aliasPath to PhaseAction; compiler sets aliasPath to
   'onboard.log' for the onboarding profile action; orchestrator
   copies the action evidence log to the alias on success. Best-
   effort - alias copy failures do not fail the action.

Live evidence from run 26550936453 (canonical ubuntu-repo-cloud-openclaw):
- environment.install.repo-current: passed in 14.2s
- onboarding.profile.cloud-openclaw: passed in 302s (real onboarding!)
- onboarding.base.cli-installed: passed
- onboarding.preflight.passed: failed (onboard.log not found) <- fixed
- runtime.* (10 steps): all 'missing key(s)' <- fixed by #1

Tests: 38/38 phase-orchestrator (was 36; +2 alias tests), 294/294
scenario framework. shellcheck clean.

Validation gate next: redispatch e2e-scenarios-all and confirm
runtime steps actually exercise the SUT (real pass/fail, not key
errors).

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
jyaunches added a commit that referenced this pull request May 28, 2026
Addresses PR Review Advisor finding #1: 'Secret-bearing child process
output is persisted and uploaded without redaction'.

Designed in the spirit of the test/e2e-scenario architecture: secret
hygiene is FRAMEWORK INFRASTRUCTURE, not a per-script / per-action /
per-workflow concern. Same one-mode discipline that motivates the rest
of this PR (no flag, no env var, no helper bypasses redaction).

New module: test/e2e-scenario/scenarios/orchestrators/redaction.ts
  Sits next to context.ts, owns:
    - redactString(text):       canonical token-shape redaction
    - buildChildEnv(base, opts): minimal allowlisted env + declared
                                 secretEnv passthrough only
    - pipeRedacted(src, log):   single I/O wrapper used by both
                                 runAction and runShellStep
  Pattern set is a framework-local mirror of
  src/lib/security/secret-patterns.ts. The framework deliberately does
  NOT import from src/lib/security/ to keep the framework-vs-product
  boundary clean and avoid cross-tsconfig ESM issues. A new parity
  test (e2e-redaction-parity.test.ts) asserts the two pattern sets
  stay in lockstep so adding a token shape in one place keeps both
  layers honest.

Typed contract extension: PhaseAction.secretEnv?: readonly string[]
  AssertionStep.secretEnv?: readonly string[]
  Compiler decides which secrets cross the framework boundary, the
  same way aliasPath / scriptRef / timeoutSeconds are declared
  metadata. buildChildEnv enforces a 'secret-key shape' contract on
  every entry (must end with API_KEY/TOKEN/SECRET/PASSWORD/CREDENTIAL/
  PASSPHRASE/PRIVATE_KEY/ACCESS_KEY) so the secretEnv channel cannot
  silently allowlist non-secret variables.

compiler.ts: declares onboard secretEnv per profile
  cloud-* profiles -> ['NVIDIA_API_KEY']
  local-ollama-openclaw -> []
  Install actions declare nothing (the installer itself does not
  authenticate to the cloud).

phase.ts: two call sites updated, identical pattern in both
  runAction:    buildChildEnv(...) + pipeRedacted(stdout, log) +
                pipeRedacted(stderr, log, tail<-redactedChunk)
  runShellStep: same shape
  Spawn-error 'message' fields are also wrapped with redactString as
  defense-in-depth.

Workflow upload tightening (.github/workflows/e2e-scenarios.yaml):
  - include-hidden-files: false
    Hidden dotfiles under the workspace can carry raw secrets
    (notably .e2e/context.env, written by e2e_context_set without
    redaction). Diagnostic dumps of context use e2e_context_dump
    which redacts on emit.
  - path: explicit subpath list (.e2e/actions/, .e2e/logs/, result
    JSONs, plan/run-plan, onboard.log) instead of blanket .e2e/.
  workflow-boundary.mts contract test updated to assert the new
  invariant; e2e-scenarios-workflow.test.ts expectations updated.

Bash side: unchanged. test/e2e-scenario/runtime/lib/context.sh::
e2e_context_dump already redacts via _e2e_context_is_sensitive_key.
This module covers the TS-spawned-child path that lacked coverage.

Tests (e2e-phase-orchestrators.test.ts, +5):
  - test_should_not_persist_secret_shaped_child_output_into_evidence
    Real shell child writes nvapi-, ghp_, sk-, xoxb-, Bearer ...
    Asserts evidence log, phase result.json, and result.message
    contain none of the literal tokens but do contain <REDACTED>.
  - test_should_drop_non_allowlisted_parent_env_unless_declared_in_secretEnv
    Sets a sentinel parent-env var, runs child without declaring it,
    asserts child cannot see it. PATH and E2E_PHASE still arrive.
  - test_should_pass_declared_secretEnv_through_to_child
    Declares the var in step.secretEnv, asserts child sees it.
  - test_should_reject_non_secret_shaped_keys_in_secretEnv_at_runtime
    buildChildEnv throws on FOO_VAR; the secret-key-shape contract
    keeps the allowlist boundary honest.
  - test_should_declare_NVIDIA_API_KEY_only_for_cloud_onboarding_actions
    Compiler-level contract: cloud onboard declares NVIDIA_API_KEY,
    local-ollama declares nothing.

Tests (e2e-redaction-parity.test.ts, new file, +2):
  - TOKEN_PREFIX_PATTERNS framework copy matches product source
  - CONTEXT_PATTERNS framework copy matches product source

308/308 e2e-scenario framework tests pass.

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: integrations Third-party service integration behavior chore Build, CI, dependency, or tooling maintenance labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: integrations Third-party service integration behavior chore Build, CI, dependency, or tooling maintenance CI/CD Use this label to identify issues with NemoClaw CI/CD pipeline or GitHub Actions. Integration: GitHub Use this label to identify GitHub integration issues with NemoClaw.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants