Skip to content

security: disclose and detect host memory injection overlap - #4

Merged
NGO-A merged 4 commits into
masterfrom
security/nmc-host-overlap-r3
Aug 2, 2026
Merged

security: disclose and detect host memory injection overlap#4
NGO-A merged 4 commits into
masterfrom
security/nmc-host-overlap-r3

Conversation

@NGO-A

@NGO-A NGO-A commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Verification report — native-memory-citations host-overlap round 3

Date: 2026-08-01
Executor: Ninja
Base: 6c7409b5132a9a5f4c7301bf81ddc28e361e200d
Verified head: e4423dae3ce7e3f769fba99dd1e2505be8e49d13
Branch: security/nmc-host-overlap-r3
Status: PASS — ready for draft PR review

Stacking note: Retarget after PR #3 merges; PR #3 retargets after PR #2.

Changelog draft under Unreleased:

Document that redaction covers plugin-controlled surfaces only, and add a
fail-loud warning plus health finding when enhanced snapshot injection overlaps
OpenClaw host-native raw memory injection.

Scope and base controls

  • git ls-remote and the fresh clone both resolved
    security/nmc-hardening-r2 to the required immutable base
    6c7409b5132a9a5f4c7301bf81ddc28e361e200d before branching.
  • The work branch was created from that exact commit. The base branch was not
    rebased, force-pushed, retargeted, or otherwise mutated.
  • No tag, version, npm/ClawHub publish, deprecation, GHSA, release-owner step,
    runtime dependency, merge, or reporter attribution occurred.

Commit sequence

  1. c2dd1ebdocs: disclose host memory injection overlap
  2. 13462e2fix: warn on host memory injection overlap
  3. e4423dadocs: draft host injection upstream follow-up

The upstream issue text is a release-owner draft artifact outside the plugin repo at
artifacts/handoffs/upstream-host-injection-redaction-issue-draft.md; C3 contains
the matching Unreleased changelog entry. It was not filed.

Empirical host configuration key

Discovered key: agents.defaults.contextInjection.

Evidence:

  • The E12 scratch gateway profiles
    /tmp/nmc-gateway-e2e-20260801-tE7jqe/config-bounded.json and
    config-enhanced.json contain no agents.defaults.contextInjection override.
  • The installed openclaw@2026.6.9 dev-dependency declares
    AgentContextInjection = "always" | "continuation-skip" | "never" and
    AgentDefaultsConfig.contextInjection in
    node_modules/openclaw/dist/types.openclaw-*.d.ts.
  • Its bundled docs/gateway/config-agents.md states that always is the default.
  • Per-agent agents.list[].contextInjection overrides are also typed. The guard
    treats an explicit default never plus no re-enabling override as disabled.

The stop condition did not apply. Unknown or malformed versioned shapes return an
unknown state and fail open with a warning; they are never interpreted as disabled.

Guard scenario matrix

Scenario Runtime warning Health finding Result
Enhanced plugin injection + omitted host policy (host default always) yes yes PASS
Host policy never + no re-enabling per-agent override no no PASS
Plugin injection disabled no no PASS
Bounded mode no guard registration/output no PASS
Host config accessor throws failed-open warning at registration and cron_changed; no throw unknown-shape health finding when directly evaluated PASS

Focused test command:

npx vitest run src/index.test.ts --no-file-parallelism

Result: 26/26 passed.

The built plugin was also loaded with an isolated OpenClaw 2026.7.1-2 doctor
profile. Doctor emitted:

native-memory-citations: host injects raw memory content; plugin redaction does not cover host paths — see SECURITY.md

Direct SDK registry verification with getHealthCheck() confirmed that
native-memory-citations/host-injection-overlap is registered and returns a warning
finding with ocPath: agents.defaults.contextInjection.

Observed-adjacent host behavior: OpenClaw doctor --lint --only enumerates its check
IDs before the external plugin is loaded, so plugin-contributed health IDs are not
selectable in that CLI path on tested OpenClaw 2026.6.9 or 2026.7.1-2. The
registration-time warning is nevertheless visible during doctor/plugin loading and
the health finding exists in the shared SDK registry. No plugin change was added
outside this handoff to alter host doctor enumeration.

Full verification battery

Environment:

  • OS: Ubuntu Linux, kernel 7.0.0-28-generic, x86_64
  • Node: v24.18.1
  • npm: 11.16.0
  • Dev-dependency OpenClaw: 2026.6.9
  • Installed gateway/doctor OpenClaw used for the isolated load check: 2026.7.1-2
Check Result
npm ci PASS; package lock unchanged
npm run test:typecheck PASS
npm test PASS — 146/146 tests across 6 files
npm run test:stress PASS — 14/14
npm run test:coverage PASS — statements 88.31%, branches 86.90%, functions 91.24%, lines 88.31%
Enforced floors PASS — 88/85/90/88
npm run plugin:build:check PASS — “Plugin metadata is up to date”
git diff --check 6c7409b..HEAD PASS
Fresh-clone worktree status clean

npm ci reported the existing dependency audit state (12 findings) without changing
the lockfile. Round 3 adds no dependency.

Plugin-side E12 redaction recheck

Command:

npx vitest run src/index.test.ts --no-file-parallelism \
  -t "redacts secrets before writing and injecting enhanced snapshots"

Result: PASS. A secret-bearing MEMORY.md fixture produced a snapshot and injected
context containing the redaction marker and zero occurrences of the raw controlled
value. This rechecks the plugin side of E12 only; host-native raw injection remains
outside plugin control and is the condition disclosed and detected by this round.

Documentation no-daylight check

PASS.

  • SECURITY.md names every plugin-controlled redaction surface and explicitly excludes
    OpenClaw's independent workspace-bootstrap path.
  • It states that raw memory can reach model context and trajectory diagnostics through
    that host path, and that log retention is a secret-handling concern.
  • It names the host control and warns about per-agent re-enabling overrides.
  • It describes the warning/finding as detection, not host-path redaction or blocking.
  • README cross-links the exact SECURITY.md section from its redaction discussion.
  • The plugin's own guarantees were not weakened.

A reader of either document cannot reasonably conclude that installing the plugin
prevents raw host-native memory from reaching the model on a default OpenClaw host.

File-scope audit

Files changed relative to PR #3 head:

CHANGELOG.md
README.md
SECURITY.md
src/core.ts
src/enhanced.ts
src/health.ts
src/index.test.ts

Every changed file is explicitly required by WO-R3-1, WO-R3-2, its tests, or the
ordered changelog draft. No other PR #2/#3 file was touched.

Draft artifact

G1 draft created at:

artifacts/handoffs/upstream-host-injection-redaction-issue-draft.md

It requests a pre-injection redaction hook, alternatively per-workspace suppression,
trajectory diagnostic scrubbing/retention policy, and discoverable injection state.
It contains no workspace paths, fixture secrets, or reporter names. Mo owns filing.

Merge posture and owner ledger

This stacked round-3 PR must target security/nmc-hardening-r2 and remain draft.
Retarget only after PR #3 merges; PR #3 itself retargets only after PR #2. Round 3
does not change PR #3's existing merge posture: Windows remains its only open
platform surface.

Mo-owned and not performed:

  1. File the separate round-2 SDK-registration upstream issue.
  2. File this round-3 host-injection upstream issue after G1 review.
  3. Update the Sovereign Memory Gateway Notion threat-model mapping.

All explicitly out-of-scope adjacent items remain unimplemented.

@NGO-A
NGO-A changed the base branch from security/nmc-hardening-r2 to master August 2, 2026 11:55
@NGO-A
NGO-A marked this pull request as ready for review August 2, 2026 11:58
@NGO-A
NGO-A merged commit a9a9943 into master Aug 2, 2026
13 checks passed
@NGO-A

NGO-A commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author

REPORT — Full merge sequence (all phases), @ngo-a/native-memory-citations

Date: 2026-08-02
Authorization: artifacts/handoffs/authorization-2026-08-01-nmc-merge-sequence-all-phases.md
Status: Completed through Phase 4; hard stop active. This was not a release.

Merge record

All three PRs are merged with true merge commits:

PR Merge commit First parent Second parent / merged head
#2 de224446b392a426a3e88802ab238d2c12692d0d becb6fa1e0ca6d0a8238c566de1383aac6afc74b 4855a15b201e2172b6c4534ea3b72c8f04c68a97
#3 a206aaa7ea069110a29fb0e441f5626e7c1c9ebc de224446b392a426a3e88802ab238d2c12692d0d ae61e7eca717bc50b9f6da1ac644ee09adaa72d3
#4 a9a99438c310f3d1b880e5318cabdb24e9b4fcff a206aaa7ea069110a29fb0e441f5626e7c1c9ebc fccea364625f9b20d6b2da475b4521961f1b3fb5

PR #3 recomputed to exactly the 12 authorized round-2 commits before fixes. PR #4 recomputed to exactly the three authorized round-3 commits (c2dd1eb, 13462e2, e4423da) before its test-only successor. Both merge trees were conflict-free; no rebase, force-push, squash, or history rewrite occurred.

Matrix evidence

Each run used the 12 named tuples: Ubuntu/macOS/Windows × Node 22.19.0/24.x × OpenClaw 2026.6.8/2026.6.9.

PR #3 first runs and finals

  • Run 30746220794, head 310af48: Ubuntu 4/4 success; macOS 0/4; Windows 0/4. macOS/Windows were non-blocking on this first run. All eight failures were the same false workspace-escape finding caused by canonical path spelling for missing default roots.
  • Run 30746321594, head 112f5be: Ubuntu 4/4 and macOS 4/4 success; Windows 3/4 success. Windows Node 22.19.0 + OpenClaw 2026.6.9 failed with EPERM during concurrent graph-sidecar replacement.
  • Run 30746434982, head 413d9ea: all 12/12 success, including Windows 4/4.
  • Blocking final run 30746542275, head ae61e7e: all 12/12 success after removing non-blocking semantics.
  • Post-merge master run 30746645489, merge a206aaa: all 12/12 success.

PR #4 and final master

  • PR run 30746766559, head fccea36: all 12/12 success, including the round-3 guard and per-agent override test on macOS/Windows.
  • Post-merge master run 30746863178, merge a9a9943: all 12/12 success.

GitHub Actions may display the first two PR #3 workflow conclusions as success because macOS/Windows were still continue-on-error; the per-job outcomes above preserve the actual lane results verbatim.

Fix and closure commits

Commit Purpose Evidence
310af48e9a40547185c2b88f78048d20c01e0d79 Moved pull_request from invalid permissions placement into the workflow trigger so the hosted matrix could run. All subsequent PR matrices instantiated 12 tuples.
112f5be71e42ce6efc6d430f7b0df2fa0970a7c3 Canonicalized missing default roots relative to the real workspace path across macOS/Windows. macOS 4/4 green on the next run; named symlink/canonicalization test added.
413d9ea7d03223989df99139b353904453158439 Serialized concurrent atomic writes per sidecar path, preserving Windows backup/restore behavior. Windows 4/4 green on the next and every final run; concurrent-replacement test added.
ae61e7eca717bc50b9f6da1ac644ee09adaa72d3 Removed the macOS/Windows non-blocking guard. Blocking final PR #3 matrix 12/12 green.
fccea364625f9b20d6b2da475b4521961f1b3fb5 Test-only closure of the delegated per-agent override review item. Test name: warns and reports health when a per-agent override re-enables host injection; asserts both warning and health finding; full matrix 12/12 green.

Branch protection

master branch protection is active. strict is false so the audited stacked heads did not require an extra base-merge commit. All 12 exact matrix contexts are required:

  • build-validate-test (ubuntu-latest, 22.19.0, 2026.6.8)
  • build-validate-test (ubuntu-latest, 22.19.0, 2026.6.9)
  • build-validate-test (ubuntu-latest, 24.x, 2026.6.8)
  • build-validate-test (ubuntu-latest, 24.x, 2026.6.9)
  • build-validate-test (macos-latest, 22.19.0, 2026.6.8)
  • build-validate-test (macos-latest, 22.19.0, 2026.6.9)
  • build-validate-test (macos-latest, 24.x, 2026.6.8)
  • build-validate-test (macos-latest, 24.x, 2026.6.9)
  • build-validate-test (windows-latest, 22.19.0, 2026.6.8)
  • build-validate-test (windows-latest, 22.19.0, 2026.6.9)
  • build-validate-test (windows-latest, 24.x, 2026.6.8)
  • build-validate-test (windows-latest, 24.x, 2026.6.9)

Release-boundary verification

  • Remote tag baseline and final state both end at existing v2026.6.18; no tag was created or pushed by this sequence. Final complete tag-list SHA-256: f07586ea731925638022956eff34afc667620fa90396e5a34f7480e1969aa684.
  • npm still serves @ngo-a/native-memory-citations@2026.6.18, the same version recorded before Phase 1; nothing was published.
  • CHANGELOG.md on final master keeps all merged work under ## [Unreleased]; no new version was stamped.
  • No ClawHub action, npm publish, deprecation, GHSA action, upstream filing, Notion edit, reporter attribution, or runtime dependency change was performed.

Hard stop / owner-only remainder

The merge sequence is complete and stopped. Remaining owner-only work is unchanged: any later release decision and release steps; the five staged 2026.6.17 steps in their standing order; filing both upstream issues; and the Notion threat-model mapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant