fix(images): require trusted base image overrides - #6884
Conversation
Signed-off-by: Ho Lim <subhoya@gmail.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughSandbox base-image builds now record provenance, while override resolution validates trusted remote references, immutable digests, and image-ID-bound local images. Rebuild flows carry trusted local proofs, tests cover acceptance and rejection paths, and command documentation records per-agent requirements. ChangesSandbox base-image provenance and override validation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant RebuildPreflight
participant AgentBaseImage
participant resolveSandboxBaseImage
participant Docker
RebuildPreflight->>AgentBaseImage: resolve base image
AgentBaseImage->>resolveSandboxBaseImage: pass trusted local proof or override
resolveSandboxBaseImage->>Docker: inspect local image or refresh remote reference
Docker-->>resolveSandboxBaseImage: image ID, provenance, or immutable digest
resolveSandboxBaseImage-->>AgentBaseImage: validated image result
AgentBaseImage-->>RebuildPreflight: image reference and trusted override
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
PR Review Advisor — InformationalAdvisor assessment: Informational / high confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/lib/sandbox-base-image-resolution.test.ts (1)
193-280: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider extracting a small helper for the repeated override-options spread.
All four tests repeat
{ ...options, envVar: "NEMOCLAW_SANDBOX_BASE_IMAGE_REF", env: { ...options.env, NEMOCLAW_SANDBOX_BASE_IMAGE_REF: <ref> } }. A tinywithOverride(ref)helper would reduce duplication as more override scenarios are added.♻️ Example helper
function withOverride(options: ReturnType<typeof resolutionOptions>, ref: string) { return { ...options, envVar: "NEMOCLAW_SANDBOX_BASE_IMAGE_REF", env: { ...options.env, NEMOCLAW_SANDBOX_BASE_IMAGE_REF: ref }, }; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lib/sandbox-base-image-resolution.test.ts` around lines 193 - 280, Extract a small helper near the test setup, such as withOverride, that accepts the result of resolutionOptions and an override reference, then returns the shared options/env structure for NEMOCLAW_SANDBOX_BASE_IMAGE_REF. Replace the repeated inline spreads in all four resolveSandboxBaseImage tests with this helper while preserving each test’s reference value and assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/reference/commands.mdx`:
- Line 3436: In the documentation text near the remote override requirements,
place each sentence on its own source line: keep the remote NVIDIA sandbox-base
repository and immutable digest requirement together, then put the
repository-built local override tag requirement on the following line. Preserve
the wording and rendering.
In `@src/lib/sandbox-base-image.ts`:
- Around line 389-403: Update the override resolution flow in the surrounding
base-image resolver so floating remote tag overrides refresh or pull the image
before `resolvePulledCandidate` trusts `RepoDigests`. Preserve
`resolveContentAddressedLocalOverride` for immutable local overrides, but ensure
tag-based overrides cannot use stale locally cached digest metadata and must
resolve a fresh trusted registry digest.
---
Nitpick comments:
In `@src/lib/sandbox-base-image-resolution.test.ts`:
- Around line 193-280: Extract a small helper near the test setup, such as
withOverride, that accepts the result of resolutionOptions and an override
reference, then returns the shared options/env structure for
NEMOCLAW_SANDBOX_BASE_IMAGE_REF. Replace the repeated inline spreads in all four
resolveSandboxBaseImage tests with this helper while preserving each test’s
reference value and assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: e1a2ffaa-c1df-4fea-b10e-4d357d5d67b4
📒 Files selected for processing (3)
docs/reference/commands.mdxsrc/lib/sandbox-base-image-resolution.test.tssrc/lib/sandbox-base-image.ts
Signed-off-by: Ho Lim <subhoya@gmail.com>
|
✨ Thanks for the fix. Hardening sandbox base-image trust boundaries to fail closed on untrusted overrides improves deployment security. Ready for maintainer review. Related open issues: Related open issues: |
prekshivyas
left a comment
There was a problem hiding this comment.
Reviewed the remote repository restriction, digest refresh/pinning, content-addressed local override validation, ABI/runtime checks, and regression coverage. No blocking findings.
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas
left a comment
There was a problem hiding this comment.
Re-reviewed the current head after syncing main. The integration fixture now uses the immutable official-repository digest required by the new provenance contract; the resolver suite passes 19/19 and affected onboarding suites pass 12/12.
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas
left a comment
There was a problem hiding this comment.
Re-reviewed at c4f33ec: content-addressed local overrides now require a full-source-revision and current-input fingerprint stamped by NemoClaw local builds. Arbitrary matching-ID retags fail closed; focused resolver, source-identity, Docker adapter tests and CLI build/typecheck pass.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/adapters/docker/image.ts`:
- Around line 36-38: Update the label sorting comparator in the
Object.entries(...).sort chain to use direct code-unit ordering with -1, 1, or 0
based on left and right comparisons, replacing localeCompare so argv generation
remains deterministic across locales.
In `@src/lib/agent/base-image.test.ts`:
- Around line 176-182: Update the test around the provenance label assertion to
use deterministic source inputs and verify the exact expected derived provenance
key rather than only matching a 64-character hexadecimal format. Alternatively,
vary a provenance source value and assert that the emitted label changes, while
preserving the existing container execution options.
In `@src/lib/sandbox-base-image/resolution-key.ts`:
- Around line 51-60: Strengthen local base-image provenance so
createSandboxBaseImageBuildProvenanceKey is not the sole trust mechanism. Update
resolveContentAddressedLocalOverride to accept an image only when its provenance
is backed by an external attestation/signature or a repository-owned mapping,
rather than trusting the image’s own label; preserve the existing override
behavior only after that verification succeeds.
In `@src/lib/sandbox-base-image/source-identity.test.ts`:
- Around line 170-176: Update the test around getSourceRevisionIds to stub the
git subprocess so it returns a failed result without launching the real command,
then restore the stub after the assertion. Keep the invalid repository path and
ensure the assertion depends solely on GITHUB_SHA.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: ac1f9286-5595-4224-b2be-44492c4c418c
📒 Files selected for processing (10)
src/lib/adapters/docker/image.tssrc/lib/adapters/docker/index.test.tssrc/lib/agent/base-image.test.tssrc/lib/agent/base-image.tssrc/lib/sandbox-base-image-resolution.test.tssrc/lib/sandbox-base-image.tssrc/lib/sandbox-base-image/resolution-key.tssrc/lib/sandbox-base-image/source-identity.test.tssrc/lib/sandbox-base-image/source-identity.tssrc/lib/sandbox-base-image/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/sandbox-base-image.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
prekshivyas
left a comment
There was a problem hiding this comment.
Re-reviewed at 13b0db1: local override trust is now a per-build capability with a fresh nonce, not a self-asserted image label. Matching-ID images with copied provenance are rejected without the current operation proof. Deterministic argv, exact provenance wiring, isolated source identity, resolver and agent regressions all pass.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/helpers/base-image-test-harness.ts (1)
92-135: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExpose
dockerInfoFormatMockfromwithMockedDocker
The harness already patches and restores this mock, so returning it with the other deps keeps the helper symmetrical and lets tests override host-platform reporting when needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/helpers/base-image-test-harness.ts` around lines 92 - 135, Update withMockedDocker to include dockerInfoFormatMock in its returned dependencies alongside the other Docker mocks. Keep the existing patching and restoration behavior unchanged so callers can override host-platform reporting through the exposed mock.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@test/helpers/base-image-test-harness.ts`:
- Around line 92-135: Update withMockedDocker to include dockerInfoFormatMock in
its returned dependencies alongside the other Docker mocks. Keep the existing
patching and restoration behavior unchanged so callers can override
host-platform reporting through the exposed mock.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 04820c81-515c-42dd-bfaa-cb25d97eedb9
📒 Files selected for processing (10)
docs/reference/commands.mdxsrc/lib/adapters/docker/image.tssrc/lib/agent/base-image.test.tssrc/lib/agent/base-image.tssrc/lib/sandbox-base-image-resolution.test.tssrc/lib/sandbox-base-image.tssrc/lib/sandbox-base-image/resolution-key.tssrc/lib/sandbox-base-image/source-identity.tssrc/lib/sandbox-base-image/types.tstest/helpers/base-image-test-harness.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/lib/adapters/docker/image.ts
- src/lib/agent/base-image.ts
- docs/reference/commands.mdx
- src/lib/sandbox-base-image.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
|
@cv Exact-head E2E authorization is the only remaining gate for |
<!-- markdownlint-disable MD041 --> ## Summary The Hermes rebuild lanes now bootstrap their dependencies once, pull a digest-pinned historical fixture, and carry the exact validated current-base identity through the immutable rebuild handoff. Repeated `ubuntu-latest` samples reduced the normal median from 1000.5s to 618.5s (38.2%) and the stale-base median from 1068s to 614.5s (42.5%) without weakening state, readiness, replacement, or provenance assertions. This is incremental progress toward #7144. It does not implement or waive the issue's reusable cross-job BuildKit cache requirement, so #7144 remains open. ## Related Issue Part of #7144 ## Changes - Pull the historical Hermes fixture by immutable digest, verify its provenance before use, reuse the prepared current base across rebuild phases, and keep the stale-base refresh boundary intact. - Separate OpenShell/bootstrap setup from the timed rebuild contract and emit per-phase timing plus runner-resource evidence for comparable repeated samples. - Preserve state more defensively by failing closed on SQLite backup errors or missing state files and by cleaning temporary immutable base-image handoffs. - Carry validated base resolution metadata through recreate, managed Dockerfile preparation, and the final image labels so the rebuilt sandbox proves the exact phase-one base identity. - Reconcile the rebuild handoff with #6884's approved trust contract: locally built bases carry the signed per-operation provenance lease, pinned official bases retain the stricter immutable identity/ABI/runtime binder, and arbitrary local aliases remain rejected. Focused base-image and rebuild-preflight tests protect both paths. - Verify backup/restore, sandbox replacement, readiness, state schema, base layers, image labels, and current/stale lane behavior in focused and live E2E coverage. - Keep the existing Docker-engine cache security boundary. This PR does not add an external Buildx builder, registry cache, or reusable cross-job BuildKit cache; that requirement remains open in #7144 pending its security-design decision. ## 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: - [ ] Docs updated for user-facing behavior changes - [x] Docs not applicable — justification: this changes internal rebuild implementation and E2E coverage without adding a command, option, environment variable, migration, or user choice; the required docs review found existing rebuild and base-image validation documentation already accurate. - [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: provenance remains fail-closed for arbitrary aliases and is adopted only after exact immutable identity, platform, official digest, ABI, and Hermes runtime proof. Focused negative tests cover every rejected mismatch; earlier live samples exercised the normal and stale-base behaviors, and final exact-head E2E remains pending after branch convergence. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: the focused reconciliation suite passed 129 tests; `npm run build:cli` and `npm run typecheck:cli` passed; exact-head GitHub CI is running and protected E2E remains pending. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: not run; diff-scoped hooks and focused runtime/support tests cover the changed rebuild contract. - [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: Apurv Kumaria <akumaria@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Hermes rebuilds by preserving and validating base-image identity/provenance across phases, including correct reuse handling and immutable temporary handoffs. * Added safer temporary base-image handoff cleanup with best-effort disposal and retry on cleanup failures. * Rebuilds now abort when required sandbox state files fail to back up, unless `--force` is enabled. * Improved SQLite backup/restore reliability via isolated Python execution and stricter empty-output failure handling. * **New Features** * Hermes rebuild flow now carries pre-resolved base-image provenance into target/image preflights. * Added trusted local override support and scoped base-image reuse tagging/cleanup. * **Tests** * Expanded Hermes end-to-end coverage (base identity evidence, reuse planning, stale-base classification, cleanup/disposal, and workflow boundary validation), including OpenShell binary install/version checks. * **Documentation** * Clarified `--force` behavior for manifest-declared state file backup failures and updated sandbox base-image override constraints. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Ho Lim <subhoya@gmail.com> Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> Co-authored-by: Ho Lim <subhoya@gmail.com> Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: cjagwani <cjagwani@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Adds the canonical pre-tag `## v0.0.95` release entry to `docs/changelog/2026-07-24.mdx`, before the existing v0.0.94 entry. The entry summarizes approved user-visible changes merged since v0.0.94 and excludes internal-only prerequisites. ## Changes - Adds the v0.0.95 summary and detailed bullets for gateway lifecycle, recovery, state transfer, inference compatibility, sandbox security, Discord policy, and E2E evidence. - Links each user-facing theme to the most specific published documentation. - Records the release entry in the shared native changelog used by the OpenClaw, Hermes, and Deep Agents guides. Source summary: - [#7246](#7246), [#7228](#7228), [#7267](#7267), [#7489](#7489), [#7509](#7509), [#7351](#7351), and [#7290](#7290) -> `docs/changelog/2026-07-24.mdx`: Gateway authority, forward teardown and retry, managed recovery, Hermes restart recovery, scoped uninstall, and orphan-aware backup behavior. - [#7344](#7344) and [#7416](#7416) -> `docs/changelog/2026-07-24.mdx`: Atomic SQLite restore and host download verification. - [#7476](#7476), [#7347](#7347), [#7281](#7281), [#7485](#7485), [#7491](#7491), and [#7422](#7422) -> `docs/changelog/2026-07-24.mdx`: Windows Ollama reuse, CDI fallback, bounded OpenRouter connection setup, Nemotron-3 request compatibility, and managed Deep Agents retry and provider-error behavior. - [#6884](#6884), [#7481](#7481), [#6878](#6878), [#7467](#7467), [#7502](#7502), [#7503](#7503), [#7504](#7504), and [#7486](#7486) -> `docs/changelog/2026-07-24.mdx`: Trusted base-image overrides, local rebuild images, runtime validation, config preservation, reviewed package updates, and fewer final-image payload layers. - [#7303](#7303) -> `docs/changelog/2026-07-24.mdx`: Scoped Discord application-command management. - [#7488](#7488), [#7465](#7465), [#7497](#7497), [#7464](#7464), [#7501](#7501), [#7494](#7494), and [#7493](#7493) -> `docs/changelog/2026-07-24.mdx`: Selected-test risk signals, retry cleanup, full root-image validation, direct-main Hermes setup, executed PR-gate evidence, nightly history, and runner wait reporting. - [#7447](#7447) is an internal pinned-runtime prerequisite and is intentionally excluded from canonical supported-integration documentation. - [#7370](#7370) adds maintainer-only advisory reconciliation tooling and does not change supported user behavior. - [#7495](#7495) updates existing documentation and does not add a new v0.0.95 behavior claim. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: `test/changelog-docs.test.ts` validates the dated changelog structure, heading uniqueness, and published links. - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: `docs/changelog/2026-07-24.mdx`; writing rules, documentation style, factual release meaning, and published links reviewed at exact head `58b02f2bf`. - Agent: Codex documentation writer reviewer <!-- docs-review-head-sha: 58b02f2 --> <!-- docs-review-agents-blob-sha: 9c9b36d --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: `npx vitest run test/changelog-docs.test.ts` passed 6 tests. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [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) — the build passed with 0 errors and 2 Fern warnings. - [x] 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: Senthil Ravichandran <senthilr@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added a new v0.0.95 changelog entry above v0.0.94. * Documented improved externally supervised gateway lifecycle ownership. * Improved snapshot restore reliability and SQLite state handling. * Tightened CLI `backup-all` behavior and host artifact verification. * Updated Windows onboarding guidance (including Ollama service reuse and CDI directory fallback). * Noted inference compatibility fixes, deeper agent failure classification, stricter base-image validation, updated Discord bot command permissions, and refined E2E release automation evidence handling. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Senthil Ravichandran <senthilr@nvidia.com>
Summary
Refresh #6884 onto current
mainafter the trusted base-image override implementation and its regression coverage landed independently.The effective delta keeps the existing command reference source aligned with the writing guide and makes its JSONL redaction fixture safe for gitleaks to scan during merge commits.
Related Issue
Refs #5896.
Changes
mainand preserve its base-image provenance implementation and coveragemainType of Change
Quality Gates
mainalready documents the trusted override behavior; the effective docs diff only applies sentence-per-line formatting and does not change rendered meaning.APPROVEDafter the synchronized head was pushed.Documentation Writer Review
docs-updateddocs/reference/commands.mdxsentence-per-line formatting and a JSONL test-fixture correction. The command reference accurately documents trusted remote digests and current-operation local build proof. Terminology, structure, voice, and code presentation comply with repository guidance.npm run docscompleted with 0 errors and 2 known warnings.DGX Station Hardware Evidence
scripts/prepare-dgx-station-host.shis unchanged.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablesrc/lib/sandbox-base-image-resolution.test.tssuite: 22 passed;src/lib/onboard/machine/jsonl-events.test.ts: 22 passed.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — not applicable because the effective diff contains regression tests, a test fixture, and command-reference prose; targeted tests andnpm run check:diffpassed.npm run docsbuilds without warnings (doc changes only) — completed with 0 errors and 2 known warnings.Signed-off-by: Ho Lim subhoya@gmail.com