Skip to content

refactor(hermes): define path ownership contract - #8084

Closed
jyaunches wants to merge 3 commits into
mainfrom
codex/issue-8006-hermes-ownership-contract
Closed

refactor(hermes): define path ownership contract#8084
jyaunches wants to merge 3 commits into
mainfrom
codex/issue-8006-hermes-ownership-contract

Conversation

@jyaunches

@jyaunches jyaunches commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Defines one typed Hermes path ownership contract for configuration, credentials, runtime state, durable state, and disposable artifacts. This is the contract-only first step of #8006; no production consumer changes in this PR.

The follow-up stack is:

  • #8006: migrate the current Hermes path consumers to this contract, then remove broad-permission and mixed-home assumptions. These two follow-up steps remain in refactor(hermes): separate configuration, runtime, and durable state ownership #8006 because it has no child issues.
  • #8009: migrate durable-state, backup, and restore consumers, then remove the old manifest duplication.
  • #8010: migrate gateway lifecycle consumers, then remove the obsolete lifecycle patch.
  • #8007: consolidate the remaining compatibility paths after the replacement contracts land.

Estimated follow-up simplification: the currently measurable follow-up work is expected to delete roughly 650–900 existing production lines. Contract-driven executors and adapters are expected to add about 350–500 production lines, leaving an estimated net reduction of 200–450 production lines. This estimate excludes tests, the contract added here, and compatibility code that cannot be retired until its support window closes; it also does not credit later #8010 or #8007 removals that are not yet measurable.

Related Issue

Part of #8006

Changes

  • Add a typed artifact catalog with ownership, mode, Shields, backup, restore, and migration requirements for default and named-profile homes.
  • Add a resolver for managed targets and legacy migration sources, including deterministic precedence and invalid-path rejection.
  • Protect pairing approvals, separate transient pairing state, exclude raw WhatsApp session credentials from ordinary backups, and record the privileged consumer transitions still required by refactor(hermes): separate configuration, runtime, and durable state ownership #8006.
  • Add characterization and lifecycle tests for cross-identity postures, backup selection, migration retention, topology parity, and ancestor replacement boundaries.

Type of Change

  • 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

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: This internal contract has no production consumer and changes no public API, CLI, configuration, workflow, default, error, or supported behavior.
  • 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: Nine-category security and product-scope review passed for commit SHA 2e40195291c17ab3db332f019daa3c99b8de152c against base SHA 4cd4d64fe67143b57707f874afa0b9d269dfeff2.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: The independent documentation review for commit SHA 2e4019529 found the same three internal contract/test files byte-identical to commit 04430e2, with no production consumer. No user-facing documentation or Fern change is required.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npm run test:changed: 2 files and 44 tests passed; npm run typecheck:cli passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — not applicable to a contract-only source change with focused coverage.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Julie Yaunches jyaunches@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added comprehensive management for application files across profiles, runtime data, databases, credentials, caches, and staging areas.
    • Improved backup, restore, migration, and path resolution behavior across supported deployment layouts.
    • Added safeguards for invalid paths, unsafe profile names, ambiguous locations, and unsupported residual files.
    • Added selective backup handling for relevant board data and database companion files.
  • Tests

    • Added extensive coverage for ownership, permissions, lifecycle transitions, migration scenarios, and security boundaries.

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@jyaunches jyaunches self-assigned this Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds Hermes filesystem ownership contracts, managed-artifact metadata, topology-aware posture resolution, backup and restore rules, migration handling, path matching, and extensive lifecycle tests.

Hermes path ownership

Layer / File(s) Summary
Ownership contracts and artifact catalog
src/lib/agent/hermes-path-ownership.ts
Defines Hermes artifact types, ownership postures, lifecycle rules, backup policies, migration sources, SQLite sidecars, and managed artifacts.
Validation and path resolution
src/lib/agent/hermes-path-ownership.ts
Validates homes and profile names, matches canonical and recursive paths, resolves topology identities and postures, and finds managed artifacts.
Core contract validation
src/lib/agent/hermes-path-ownership.test.ts
Tests artifact completeness, runtime layouts, residual paths, topology behavior, identities, sidecars, locks, and lifecycle policies.
Lifecycle and migration validation
src/lib/agent/hermes-path-ownership-lifecycle.test.ts
Tests writable and protected state, selective backups, disposable files, path safety, migration retention, and contract gaps.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant findHermesManagedArtifact
  participant HermesHomeResolution
  participant HermesManagedArtifactCatalog
  Caller->>findHermesManagedArtifact: absolute path
  findHermesManagedArtifact->>HermesHomeResolution: identify applicable home
  HermesHomeResolution-->>findHermesManagedArtifact: home and relative path
  findHermesManagedArtifact->>HermesManagedArtifactCatalog: match artifact contract
  HermesManagedArtifactCatalog-->>findHermesManagedArtifact: artifact and path role
  findHermesManagedArtifact-->>Caller: resolved artifact or null
Loading

Suggested labels: integration: hermes, chore

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: defining the Hermes path ownership contract.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-8006-hermes-ownership-contract

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 2e40195 in the codex/issue-8006-her... branch remains at 96%, unchanged from commit 4cd4d64 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 2e40195 in the codex/issue-8006-her... branch remains at 81%, unchanged from commit a931be4 in the main branch.

Show a code coverage summary of the most impacted files.
File main a931be4 codex/issue-8006-her... 2e40195 +/-
src/lib/policy/...ne-exclusion.ts 97% 92% -5%
src/lib/private-networks.ts 93% 90% -3%
src/lib/sandbox...rce-identity.ts 88% 88% 0%
src/lib/state/g...way-registry.ts 94% 94% 0%
src/lib/state/m...-acquisition.ts 75% 75% 0%
src/lib/tunnel/services.ts 76% 76% 0%
src/lib/onboard...shboard-port.ts 90% 96% +6%
src/lib/agent/h...th-ownership.ts 0% 95% +95%

Updated August 03, 2026 08:45 UTC

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections differ; Nemotron reported the same number of blockers, 1 fewer warning, the same number of suggestions.
8 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • pathRole at src/lib/agent/hermes-path-ownership.ts:169: selected only by the second-opinion lane as define.
  • derived-disposable-state at src/lib/agent/hermes-path-ownership.ts:28: selected only by the second-opinion lane as define.
  • selective backup at src/lib/agent/hermes-path-ownership.ts:3827: selected only by the second-opinion lane as define.
  • HermesUnsupportedResidualPath at src/lib/agent/hermes-path-ownership.ts:172: selected only by the second-opinion lane as define.
  • migrationSources at src/lib/agent/hermes-path-ownership.ts:151: selected only by the second-opinion lane as define.
  • artifactClass at src/lib/agent/hermes-path-ownership.ts:23: selected only by the second-opinion lane as justified.
  • HermesContractGap at src/lib/agent/hermes-path-ownership.ts:180: selected only by the second-opinion lane as define.
  • producer at src/lib/agent/hermes-path-ownership.ts:15: selected only by the second-opinion lane as justified.
7 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • hermes-shields-config: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-hermes: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-hermes-stale-base: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • state-backup-restore: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • snapshot-commands: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • sandbox-survival: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • security-posture: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

5 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — target contract at src/lib/agent/hermes-path-ownership.ts:9: Keep `target contract`; its existing repository meaning matches this use.
  • established — root-separated at src/lib/agent/hermes-path-ownership-lifecycle.test.ts:21: Keep `root-separated`; the term matches existing runtime-guard and startup usage.
  • established — same-UID at src/lib/agent/hermes-path-ownership.ts:278: Keep `same-UID`; the stated credential-isolation limitation gives the modifier a concrete security contrast.
  • define — privileged transition at src/lib/agent/hermes-path-ownership.ts:185: Add a brief explanatory definition near `HermesContractGap` that names the ownership or privilege-boundary change required by this migration class.
  • established — characterization at src/lib/agent/hermes-path-ownership.ts:9: Keep `characterization`; its use matches established repository test terminology.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: full-e2e, hermes-e2e

1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Remove the unused target ownership catalog or connect it to a lifecycle consumer

  • Location: src/lib/agent/hermes-path-ownership.ts:8
  • Category: architecture
  • Problem: The new ownership catalog defines backup, restore, migration, and Shields postures, but no production code imports it. The checked-in behavior therefore remains in separate lifecycle implementations while this file can drift as a second policy source.
  • Impact: Future lifecycle changes can update either the active implementation or this catalog without changing the other, leaving security-sensitive ownership and recovery policy inconsistent.
  • Recommendation: Connect the catalog to one named current lifecycle consumer in this PR, with a contract test for that consumer. Otherwise remove the unused target catalog and retain only focused evidence needed by an active change.
  • Verification: Search production imports of `hermes-path-ownership`; only the two new test files import it.
  • Test coverage: Add a consumer-level test that changes a Hermes lifecycle input and verifies the active backup, restore, or Shields path reads the corresponding catalog rule.
  • Simplification (delete): Remove Delete the unused catalog and its tests until a lifecycle consumer can read the policy.; use Keep policy with the active consumer, or add the catalog only with the consumer migration.. Net: -5933 lines.
  • Keep: Do not remove existing ownership, backup, restore, or Shields enforcement.
  • Evidence: `src/lib/agent/hermes-path-ownership.ts:8-11` states that the file is a target contract and that later PRs will migrate consumers. Repository search for `hermes-path-ownership` found imports only in `hermes-path-ownership.test.ts` and `hermes-path-ownership-lifecycle.test.ts`.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (8)
src/lib/agent/hermes-path-ownership.ts (1)

3599-3653: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Cache pattern validation and compiled segment regexes.

matchesHermesRelativePattern calls validateHermesRelativePattern on every invocation. findHermesManagedArtifact calls it once per pattern contract per lookup. matchesPatternSegment also builds a new RegExp for every segment comparison. The catalog is a module-level constant, so both results are stable per pattern.

Memoize the validated pattern set and the compiled segment regexes in module-level Map instances. This removes repeated validation and regex compilation from each lookup.

Note on the static analysis hints for Line 3611: the regex source comes only from catalog literals that validateHermesRelativePattern already rejects when they contain * outside a ** segment. Untrusted input reaches the regex input string, not the regex source. Caching the compiled regex also bounds repeated construction.

♻️ Proposed caching of validation and compiled regexes
+const VALIDATED_PATTERNS = new Set<string>();
+const SEGMENT_MATCHERS = new Map<string, RegExp | null>();
+
 function matchesPatternSegment(patternSegment: string, candidateSegment: string): boolean {
+  let matcher = SEGMENT_MATCHERS.get(patternSegment);
+  if (matcher === undefined) {
     const placeholders = [...patternSegment.matchAll(/\{[^{}]+\}/gu)];
-  if (placeholders.length === 0) return patternSegment === candidateSegment;
-
+    if (placeholders.length === 0) {
+      SEGMENT_MATCHERS.set(patternSegment, null);
+      matcher = null;
+    } else {
       let expression = "^";
       let cursor = 0;
       for (const placeholder of placeholders) {
         const index = placeholder.index ?? 0;
         expression += patternSegment.slice(cursor, index).replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
         expression += ".+";
         cursor = index + placeholder[0].length;
       }
       expression += patternSegment.slice(cursor).replace(/[.*+?^${}()|[\]\\]/gu, "\\$&") + "$";
-  return new RegExp(expression, "u").test(candidateSegment);
+      matcher = new RegExp(expression, "u");
+      SEGMENT_MATCHERS.set(patternSegment, matcher);
+    }
+  }
+  if (matcher === null) return patternSegment === candidateSegment;
+  return matcher.test(candidateSegment);
 }
 
 function matchesHermesRelativePattern(pattern: string, candidate: string): boolean {
-  validateHermesRelativePattern(pattern);
+  if (!VALIDATED_PATTERNS.has(pattern)) {
+    validateHermesRelativePattern(pattern);
+    VALIDATED_PATTERNS.add(pattern);
+  }
🤖 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/agent/hermes-path-ownership.ts` around lines 3599 - 3653, Add
module-level caches for validated Hermes relative patterns and compiled segment
regular expressions, then update matchesHermesRelativePattern to reuse the
validation result and matchesPatternSegment to reuse compiled regexes for each
pattern segment. Preserve exact-match handling for segments without placeholders
and ensure cache keys distinguish different pattern strings or segments.

Source: Linters/SAST tools

src/lib/agent/hermes-path-ownership.test.ts (3)

63-64: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the redundant type assertion.

HERMES_MANAGED_ARTIFACTS is already typed as a readonly array of HermesManagedArtifact. The as readonly HermesManagedArtifact[] cast at Line 64 adds no information. A cast also hides a future contract change from the type checker.

♻️ Proposed simplification
-    for (const entry of HERMES_MANAGED_ARTIFACTS as readonly HermesManagedArtifact[]) {
+    for (const entry of HERMES_MANAGED_ARTIFACTS) {
🤖 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/agent/hermes-path-ownership.test.ts` around lines 63 - 64, Remove the
redundant readonly HermesManagedArtifact[] type assertion from the iteration
over HERMES_MANAGED_ARTIFACTS, leaving the existing loop and Set logic unchanged
so the array’s declared type remains enforced by the compiler.

49-158: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Split this test into separate cases.

This single test covers identity resolution, presence, path shape, lifecycle postures, shield requirements, backup and restore pairing, target uniqueness, and migration sources. The title names two of those claims. A failure in any branch reports one test.

The coding guidelines require low function complexity. Splitting also removes most of the conditionals that the growth guardrail rejects.

Suggested split, one test per invariant:

  • producers and readers resolve for every topology
  • create posture owner matches the producer
  • lifecycle postures use valid modes
  • backup and restore stay consistent
  • concrete target paths stay unique and resolve back to the artifact
  • migration sources resolve with pathRole set to migration-source

As per coding guidelines, "Keep function complexity low".

🤖 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/agent/hermes-path-ownership.test.ts` around lines 49 - 158, Split the
monolithic test around HERMES_MANAGED_ARTIFACTS into focused cases for identity
resolution, create-owner matching, lifecycle posture validity, backup/restore
consistency, target uniqueness and resolution, and migration-source resolution.
Move each related assertion block into its corresponding test, preserving the
existing topology and artifact coverage while keeping each test’s branching and
complexity low.

Sources: Coding guidelines, Pipeline failures


85-97: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the property directly instead of collapsing it to a boolean.

These assertions reduce a compound condition to true or false. Two problems follow.

  1. The failure message shows only expected true/false. It does not show the actual presence, relativePath, backup, or restore value.
  2. Lines 89-97 pass for every agent-home artifact because the entry.scope !== "agent-home" conjunct is already false. The intended rule, that only agent-home artifacts carry per-home backup and restore rules, is never checked for those artifacts.

Assert the observable values instead.

♻️ Proposed assertions
-      expect(entry.presence === "required" || entry.presence === "optional", entry.id).toBe(true);
-      expect(typeof entry.relativePath === "string" || entry.scope === "agent-home", entry.id).toBe(
-        true,
-      );
-      expect(
-        typeof entry.backup === "object" &&
-          "default" in entry.backup &&
-          entry.scope !== "agent-home",
-        entry.id,
-      ).toBe(false);
-      expect(typeof entry.restore === "object" && entry.scope !== "agent-home", entry.id).toBe(
-        false,
-      );
+      expect([entry.presence, entry.id]).toEqual([expect.stringMatching(/^(required|optional)$/u), entry.id]);
+      const homeKeyedBackup = typeof entry.backup === "object" && "default" in entry.backup;
+      const homeKeyedRestore = typeof entry.restore === "object";
+      expect({ id: entry.id, homeKeyedBackup, homeKeyedRestore }).toEqual({
+        id: entry.id,
+        homeKeyedBackup: homeKeyedBackup && entry.scope === "agent-home",
+        homeKeyedRestore: homeKeyedRestore && entry.scope === "agent-home",
+      });

Apply the same change to Line 125 and Line 137.

As per path instructions, "Prefer observable outcomes through the public boundary over source-text, private-shape, or mock-call assertions."

🤖 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/agent/hermes-path-ownership.test.ts` around lines 85 - 97, Update the
assertions in the artifact validation test, including the checks near lines 125
and 137, to assert each observable property directly rather than converting
compound conditions to booleans. Validate presence and relativePath against
their expected values, and assert backup and restore are present only for
agent-home artifacts while non-agent-home artifacts have the expected absence;
preserve the existing entry.id context in failure messages.

Source: Path instructions

src/lib/agent/hermes-path-ownership-lifecycle.test.ts (4)

266-275: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the expected artifactClass per artifact.

Line 269 accepts three of the five artifact classes for both tool-home and kanban-state. The assertion passes if either artifact changes class within that set. The test title claims the state stays writable, so the class matters.

♻️ Proposed per-artifact expectation
-    for (const id of ["tool-home", "kanban-state"]) {
-      const entry = artifact(id);
-      expect(entry.artifactClass, id).toMatch(
-        /^(credential-reference|durable-state|mutable-runtime-state)$/u,
-      );
+    for (const [id, artifactClass] of [
+      ["tool-home", "credential-reference"],
+      ["kanban-state", "durable-state"],
+    ] as const) {
+      const entry = artifact(id);
+      expect(entry.artifactClass, id).toBe(artifactClass);

Replace the placeholder values with the declared classes.

🤖 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/agent/hermes-path-ownership-lifecycle.test.ts` around lines 266 -
275, Update the test case around artifact() so each artifact uses its declared
artifactClass explicitly: expect tool-home and kanban-state to their respective
fixed classes instead of accepting a shared regular expression. Keep the
existing writable-shield and gateway producer/reader assertions unchanged.

Source: Path instructions


395-405: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move the narrowing guard before the assertion.

Line 400 uses an optional chain, so resolved can be undefined. Line 401 asserts the id and fails first. Line 402 then throws. The guard is unreachable on the failure path, and the thrown message never appears.

Place the guard first, then assert.

♻️ Proposed reordering
-      const resolved = findHermesManagedArtifact(target)?.artifact;
-      expect(resolved?.id, target).toBe(id);
-      if (!resolved) throw new Error("Missing Hermes artifact for '" + target + "'");
-      const posture = resolveHermesPosture(resolved.required.create, "root-separated", "gateway");
+      const resolution = findHermesManagedArtifact(target);
+      expect(resolution?.artifact.id, target).toBe(id);
+      const resolved = artifact(id);
+      const posture = resolveHermesPosture(resolved.required.create, "root-separated", "gateway");

The artifact(id) helper already throws a named error, so the local guard is not needed. This also removes one branch that the growth guardrail counts.

🤖 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/agent/hermes-path-ownership-lifecycle.test.ts` around lines 395 -
405, Update the loop using findHermesManagedArtifact so the missing-artifact
narrowing occurs before accessing or asserting resolved.id, ensuring the
intended error is raised first; preferably reuse the existing artifact(id)
helper’s named error and remove the redundant local guard if applicable.

Source: Pipeline failures


1014-1089: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

This assertion copies the production constant verbatim.

HERMES_CONTRACT_GAPS is asserted against a literal that duplicates src/lib/agent/hermes-path-ownership.ts lines 206-280 field for field. The test passes whenever the two literals stay in sync. It proves no behavior. Any contract edit requires the same edit here, which invites a mechanical copy of the new value.

Assert the properties that carry meaning instead. Examples:

  • every gap id is unique
  • every targetArtifactIds entry resolves through artifact(id)
  • every failure value is retain-source
  • every currentPaths entry resolves to a managed artifact or a declared migration source

That set fails when a gap points at a removed artifact. The current literal comparison does not.

The same pattern appears in src/lib/agent/hermes-path-ownership.test.ts at Lines 264-321 for HERMES_UNSUPPORTED_RESIDUAL_PATHS. That file already pairs the literal with findHermesManagedArtifact assertions at Lines 322-334, which is the stronger form.

As per path instructions, "Flag copied production algorithms, broad mocks that bypass the behavior under test, and conditionals that make a test pass without exercising its claim."

🤖 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/agent/hermes-path-ownership-lifecycle.test.ts` around lines 1014 -
1089, The test should stop comparing HERMES_CONTRACT_GAPS to a copied production
literal and instead validate its semantic invariants: unique gap ids, resolvable
targetArtifactIds via artifact, retain-source failure values, and valid
managed-artifact or declared migration-source currentPaths. Apply the same
principle to HERMES_UNSUPPORTED_RESIDUAL_PATHS in hermes-path-ownership.test.ts,
reusing its existing findHermesManagedArtifact assertions rather than
duplicating production data.

Source: Path instructions


956-982: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the manifest assertions order-independent. agents/hermes/manifest.yaml is the contract source and currently matches the test. Backup and restore do not require stateDirs or stateFiles order, so compare paths and strategies without fixing sequence order.

🤖 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/agent/hermes-path-ownership-lifecycle.test.ts` around lines 956 -
982, Update the manifest assertions in the test “records current manifest gaps
separately from the target backup contract (`#8006`)” to compare stateDirs and
stateFiles order-independently, while still requiring the same directory paths
and file path/strategy pairs. Preserve the manifest contract values without
enforcing their sequence.

Source: Learnings

🤖 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/agent/hermes-path-ownership-lifecycle.test.ts`:
- Around line 728-747: Update the table-driven expectations in the artifact
ownership test so each staging path entry explicitly provides its expected
shields value. Replace the conditional classification based on id prefixes and
special ids near the stagingPaths assertions, and compare against that per-entry
value while preserving the existing artifact metadata checks and growth
guardrail behavior.

In `@src/lib/agent/hermes-path-ownership.test.ts`:
- Around line 106-120: Remove all if statements from the changed test bodies and
local helpers in src/lib/agent/hermes-path-ownership.test.ts (including the
anchor range 106-120 and the cited ranges 72, 74-78, 120, 127, 152, and 560) by
splitting posture-kind expectations into separate tests and moving other
branches into named narrowing helpers; in
src/lib/agent/hermes-path-ownership-lifecycle.test.ts (346-406, plus 435 and
478), replace narrowing guards with a shared helper that throws and returns the
narrowed value. Move the conditional artifact helper from both files into one
shared non-test module and reuse it.

---

Nitpick comments:
In `@src/lib/agent/hermes-path-ownership-lifecycle.test.ts`:
- Around line 266-275: Update the test case around artifact() so each artifact
uses its declared artifactClass explicitly: expect tool-home and kanban-state to
their respective fixed classes instead of accepting a shared regular expression.
Keep the existing writable-shield and gateway producer/reader assertions
unchanged.
- Around line 395-405: Update the loop using findHermesManagedArtifact so the
missing-artifact narrowing occurs before accessing or asserting resolved.id,
ensuring the intended error is raised first; preferably reuse the existing
artifact(id) helper’s named error and remove the redundant local guard if
applicable.
- Around line 1014-1089: The test should stop comparing HERMES_CONTRACT_GAPS to
a copied production literal and instead validate its semantic invariants: unique
gap ids, resolvable targetArtifactIds via artifact, retain-source failure
values, and valid managed-artifact or declared migration-source currentPaths.
Apply the same principle to HERMES_UNSUPPORTED_RESIDUAL_PATHS in
hermes-path-ownership.test.ts, reusing its existing findHermesManagedArtifact
assertions rather than duplicating production data.
- Around line 956-982: Update the manifest assertions in the test “records
current manifest gaps separately from the target backup contract (`#8006`)” to
compare stateDirs and stateFiles order-independently, while still requiring the
same directory paths and file path/strategy pairs. Preserve the manifest
contract values without enforcing their sequence.

In `@src/lib/agent/hermes-path-ownership.test.ts`:
- Around line 63-64: Remove the redundant readonly HermesManagedArtifact[] type
assertion from the iteration over HERMES_MANAGED_ARTIFACTS, leaving the existing
loop and Set logic unchanged so the array’s declared type remains enforced by
the compiler.
- Around line 49-158: Split the monolithic test around HERMES_MANAGED_ARTIFACTS
into focused cases for identity resolution, create-owner matching, lifecycle
posture validity, backup/restore consistency, target uniqueness and resolution,
and migration-source resolution. Move each related assertion block into its
corresponding test, preserving the existing topology and artifact coverage while
keeping each test’s branching and complexity low.
- Around line 85-97: Update the assertions in the artifact validation test,
including the checks near lines 125 and 137, to assert each observable property
directly rather than converting compound conditions to booleans. Validate
presence and relativePath against their expected values, and assert backup and
restore are present only for agent-home artifacts while non-agent-home artifacts
have the expected absence; preserve the existing entry.id context in failure
messages.

In `@src/lib/agent/hermes-path-ownership.ts`:
- Around line 3599-3653: Add module-level caches for validated Hermes relative
patterns and compiled segment regular expressions, then update
matchesHermesRelativePattern to reuse the validation result and
matchesPatternSegment to reuse compiled regexes for each pattern segment.
Preserve exact-match handling for segments without placeholders and ensure cache
keys distinguish different pattern strings or segments.
🪄 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: f3f1e4a4-434d-41b3-a00c-3bd398a2e7ee

📥 Commits

Reviewing files that changed from the base of the PR and between f93b27d and 14f52b2.

📒 Files selected for processing (3)
  • src/lib/agent/hermes-path-ownership-lifecycle.test.ts
  • src/lib/agent/hermes-path-ownership.test.ts
  • src/lib/agent/hermes-path-ownership.ts

Comment thread src/lib/agent/hermes-path-ownership-lifecycle.test.ts
Comment thread src/lib/agent/hermes-path-ownership.test.ts Outdated
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/lib/agent/hermes-path-ownership.test.ts (1)

35-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate homesFor and homesForResidual.

homesFor and homesForResidual implement the same scope-to-home mapping. The only difference is that homesForResidual omits the "dashboard" case, since residual paths never carry that scope.

Extract the shared cases into one function and have homesForResidual call it after excluding "dashboard", or build a lookup table keyed by scope shared by both functions. This removes the duplicate mapping and avoids a case falling out of sync if a new scope value is added to only one function.

♻️ Example consolidation
-function homesFor(artifactRule: HermesManagedArtifact): HermesHome[] {
-  switch (artifactRule.scope) {
-    case "agent-home":
-      return [{ kind: "default" }, { kind: "named-profile", name: "research" }];
-    case "default-home":
-      return [{ kind: "default" }];
-    case "dashboard":
-      return [{ kind: "dashboard" }];
-    case "named-profile":
-      return [{ kind: "named-profile", name: "research" }];
-  }
-}
-
-function homesForResidual(residual: HermesUnsupportedResidual): HermesHome[] {
-  switch (residual.scope) {
-    case "agent-home":
-      return [{ kind: "default" }, { kind: "named-profile", name: "research" }];
-    case "default-home":
-      return [{ kind: "default" }];
-    case "named-profile":
-      return [{ kind: "named-profile", name: "research" }];
-  }
-}
+function homesForScope(
+  scope: "agent-home" | "default-home" | "named-profile",
+): HermesHome[] {
+  switch (scope) {
+    case "agent-home":
+      return [{ kind: "default" }, { kind: "named-profile", name: "research" }];
+    case "default-home":
+      return [{ kind: "default" }];
+    case "named-profile":
+      return [{ kind: "named-profile", name: "research" }];
+  }
+}
+
+function homesFor(artifactRule: HermesManagedArtifact): HermesHome[] {
+  return artifactRule.scope === "dashboard"
+    ? [{ kind: "dashboard" }]
+    : homesForScope(artifactRule.scope);
+}
+
+function homesForResidual(residual: HermesUnsupportedResidual): HermesHome[] {
+  return homesForScope(residual.scope);
+}
🤖 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/agent/hermes-path-ownership.test.ts` around lines 35 - 57,
Consolidate the duplicated scope-to-home mapping in homesFor and
homesForResidual by introducing one shared mapping helper or lookup table.
Preserve the dashboard mapping for HermesManagedArtifact, while ensuring
homesForResidual handles only non-dashboard scopes through the shared
implementation and remains type-safe if new scope values are added.
🤖 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 `@src/lib/agent/hermes-path-ownership.test.ts`:
- Around line 35-57: Consolidate the duplicated scope-to-home mapping in
homesFor and homesForResidual by introducing one shared mapping helper or lookup
table. Preserve the dashboard mapping for HermesManagedArtifact, while ensuring
homesForResidual handles only non-dashboard scopes through the shared
implementation and remains type-safe if new scope values are added.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5041513f-0b49-4775-8f32-cf7286c87941

📥 Commits

Reviewing files that changed from the base of the PR and between 14f52b2 and 04430e2.

📒 Files selected for processing (3)
  • src/lib/agent/hermes-path-ownership-lifecycle.test.ts
  • src/lib/agent/hermes-path-ownership.test.ts
  • src/lib/agent/hermes-path-ownership.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/agent/hermes-path-ownership-lifecycle.test.ts
  • src/lib/agent/hermes-path-ownership.ts

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
@cv

cv commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Security and product-scope review — PASS

Reviewed commit SHA 2e40195291c17ab3db332f019daa3c99b8de152c against base SHA 4cd4d64fe67143b57707f874afa0b9d269dfeff2.

Verdict

PASS. No security findings.

Issue #8006 explicitly sequences the typed ownership model and characterization tests as delivery step 1, before production consumers migrate in later steps. This pull request adds only that contract and its tests. Repository search found no production import or caller, so the change does not create a supported integration or alter current runtime behavior.

The three changed-file blobs are byte-identical to commit 04430e28e7d1ffd9bbb316d0bf3a4ed188c655e1; the merge commit changes only the base relationship.

Findings

No findings.

Detailed analysis

  1. Secrets and Credentials — PASS. No secret values, credentials, tokens, or private keys are added. The contract classifies credential-bearing state explicitly; raw WhatsApp sessions and environment credentials are excluded from ordinary backups, and transient pairing state is separated from protected approvals.
  2. Input Validation and Data Sanitization — PASS. Profile names, absolute paths, relative paths, and selector patterns use allowlisted forms and canonical-path checks. Absolute paths outside Hermes roots, unknown profile state, parent traversal, trailing separators, backslashes, malformed placeholders, and ambiguous matches are rejected. Literal pattern segments are escaped, and recursive matching is memoized.
  3. Authentication and Authorization — PASS. No runtime authentication or authorization path changes. The declarative model records producers and readers for both supported identity topologies, keeps pairing approvals root-produced and sealed, and separates gateway-writable request and rate-limit state.
  4. Dependencies and Third-Party Libraries — PASS. No dependency, lockfile, package, workflow, or external-source change. The only runtime import is node:path.
  5. Error Handling and Logging — PASS. Invalid and ambiguous inputs fail with deterministic errors. The change adds no logging, telemetry, exception suppression, or credential-bearing error path.
  6. Cryptography and Data Protection — PASS. No cryptographic behavior changes. Backup and restore rules exclude credentials, disposable database sidecars, locks, staging files, and runtime cursors while retaining declared durable state. Failed migrations retain their source, and remaining privileged transitions are recorded as contract gaps.
  7. Configuration and Security Headers — PASS. No deployed configuration, policy, container, header, or permission is changed. The contract describes narrow ownership, mode, Shields, backup, restore, and migration requirements without activating them.
  8. Security Testing — PASS. The added characterization tests cover cross-identity ownership, canonical path rejection, traversal, ambiguous resolution, recursive-pattern behavior, credential backup exclusions, protected approval state, ancestor replacement boundaries, migration retention, and selective-backup precedence. The repository checks completed for this commit SHA, including CodeQL, ShellCheck, growth guardrails, type checking, all CLI shards, installer integration, E2E gates, and the documentation-review receipt.
  9. System Security — PASS. The change performs no filesystem writes, permission changes, process execution, network access, environment access, or security-control mutation. Match resolution fails on equal specificity, and memoized recursive matching avoids combinatorial backtracking.

Product-scope and review evidence

  • Issue refactor(hermes): separate configuration, runtime, and durable state ownership #8006 establishes this contract-only foundation step and defers consumer migration and removal of broad-permission assumptions to later steps.
  • All three commits report Verified in GitHub and contain Julie Yaunches's Signed-off-by declaration.
  • Both review threads are resolved; there are zero unresolved review threads.
  • The automated review advisor reported no blocking findings. Its warning that the catalog has no production consumer describes the issue-defined sequencing for step 1.
  • Required checks are passing for commit SHA 2e40195291c17ab3db332f019daa3c99b8de152c; the changes job is skipped in the metadata-only workflow, while the code-changing workflow run completed its applicable lanes.

Files reviewed

  • src/lib/agent/hermes-path-ownership.ts
  • src/lib/agent/hermes-path-ownership.test.ts
  • src/lib/agent/hermes-path-ownership-lifecycle.test.ts

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved for commit 2e40195. Issue #8006 authorizes this contract-only step. The security review passed, the independent documentation writer review found no documentation update was needed, DCO is present, all commits are GitHub Verified, no review threads remain, and the required GitHub checks pass for this commit.

@jyaunches jyaunches closed this Aug 3, 2026
jyaunches added a commit that referenced this pull request Aug 6, 2026
## Summary

Reimplements [#8006](#8006) by
making each agent manifest the only state declaration. `loadAgent()`
validates that declaration and derives the `AgentDefinition` projections
used by backup, restore, wipe, and Shields.

This is the contract foundation for the dependent stack:
[#8010](#8010) (provider/root
mutation boundary), then
[#8009](#8009) (generic staged
restore). Merged [#7871](#7871)
now supplies the cron restore-drain guarantee; this head preserves it
while integrating the manifest-derived state contract.
[#7880](#7880) and
[#7806](#7806) are closed and
are not part of the remaining stack.

This stack does **not** promise a net source-line reduction. Its purpose
is to replace divergent state authorities with one validated contract
and make privileged state mutation safe across agent implementations.
Current estimates are:

| Follow-up | Estimated production additions | Estimated production
lines replaced or deleted from current `main` |
| --- | ---: | ---: |
| #8010 | About 520–790 for the registered-sandbox slice; 600–930 if
created/rebuild flows are included | Pending the owner-approved provider
and durable-receipt boundary; it must replace a named existing mutation
path before merge |
| #8009 | About 530 | About 100–160 |

The only presently defensible deletion estimate is therefore about
100–190 production lines. #8010 intersects the provider work in
[#7744](#7744) and durable
receipt work in [#7702](#7702);
its scope and deletion estimate remain provisional until those owners
approve or narrow the boundary.
[#7871](#7871) is merged and
incorporated in this head;
[#7880](#7880) is closed. Neither
is counted as a future deletion from `main`.

The current GitHub diff is +4,847/-948 across 105 production, test,
documentation, and tooling files.

The production increase establishes and verifies the shared contract
before later PRs consume it. The largest additions are the TypeScript
validation and derivation boundary and the descriptor-safe Python state
guard extension. The rest replaces separate behavior in backup, restore,
wipe, Shields, startup recovery, and image-version handling.

This PR does not add a policy database or handwritten registry. Each
agent manifest contains the declaration, and `AgentDefinition` is the
validated runtime authority. The generator calls `listAgents()` and
`loadAgent()` instead of maintaining an agent list or parsing YAML
separately. No code from closed
[#8084](#8084) was transferred.

## Related Issue

Fixes #8006

Parent epic: #8004

Stacked follow-ups: #8010, then #8009

## Changes

- Extends `state_dirs` with the independent facts used by current
consumers: backup inclusion, Shields mode, declared prefixes, and
writable subpaths.
- Makes `AgentDefinition` validate those declarations and derive backup,
restore, wipe, and Shields projections.
- Generates each image state-lock plan through `listAgents()` and
`loadAgent()`. `state_lock_plan_in_image` declares whether an agent
image carries that projection.
- Removes `HIGH_RISK_STATE_DIRS`, `CONFIDENTIALITY_STATE_DIRS`,
`runtime_auth_state_dirs`, the fixed `agents/*/sessions` carve-out,
literal `workspace-*` handling, and startup relock lists.
- Rejects drift between the current `AgentDefinition` and an installed
current-image plan before a privileged mutation. Older images retain the
bounded rebuild compatibility path.
- Makes backup discovery and restore authorization fail closed against
the target agent definition, including prefix matches and non-backup
authentication state.
- Routes locked OpenClaw migration through the existing configuration
and state-directory guards so a failed relock remains retryable.
- Preserves merged Hermes dashboard-profile, cron-restore, truthful
Shields rollback, and packaged-service teardown behavior from #7200,
#7871, #8198, and #8239.
- Corrects the merged #7871 rebuild E2E fixture to read the pinned flat
Hermes cron record, reject schema drift, and require newly seeded jobs
to be scheduled, then exercises stranded-gate recovery with an overdue
one-shot job from the built-in scheduler and validates exactly one
post-recovery execution through the pinned Hermes ledger.
- Treats the immediate post-restart Hermes `running_pid: null` evidence
as a bounded polling transient in the E2E fixture while keeping every
other gateway field strict; readiness still requires a new live process
identity.
- Validates the #7871 stranded-gate receipt after the E2E redaction
boundary, accepting only the exact redaction sentinel while separately
pinning the raw 32-character token contract.
- Keeps the Deep Agents Code live validation lane deterministic with
bounded retries for transient status-health failures. That lane is in
scope because #8006 changes and validates the Deep Agents manifest
alongside OpenClaw and Hermes; the retry remains fail-closed after three
attempts and does not change runtime product behavior.
- Limits the Dockerfile delta to packaging and protecting the generated
OpenClaw state-lock plan; no digest allowlist change remains in the
current diff.
- Updates security documentation and adds contract, permission, backup,
restore, wipe, image-layout, version-skew, and live E2E coverage.

The existing backup, restore, wipe, and Shields paths are the consumers
required by #8006. A direct change to one consumer would leave the
others as separate authorities. The state-directory contract tests,
snapshot contract tests, focused consumer tests, and live E2E targets
protect the shared definition.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] 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:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [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: the canonical
`nemoclaw-maintainer-security-code-review` rubric was applied against
exact base `3b208d79e5d3bda4183704145ee5c28d79876ae1` and head
`14c334aacfa1897633e5c1b383977a4333a24c1f`. All nine categories PASS
with no findings or warnings across all 105 changed files. The review
covered secrets, input validation, authorization, dependencies, error
handling, data protection, configuration, security tests, and
system-level stale-state/recovery/TOCTOU behavior. The nullable E2E PID
cannot satisfy readiness and only continues a bounded poll.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue: none accepted; required
GitHub checks and live E2E remain required before merge.

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: Reviewed the complete 105-file PR patch against the
manifest-derived state contract, snapshot authorization, per-agent
Shields plans, historical compatibility, Deep Agents host injection, and
the Hermes dashboard carve-out at exact head
`14c334aacfa1897633e5c1b383977a4333a24c1f` against base
`3b208d79e5d3bda4183704145ee5c28d79876ae1`. The final Hermes
restart-transient fixture change is E2E-only and requires no additional
user documentation. `npm run docs` passed with 0 errors and 2 existing
Fern warnings; route validation passed for 67 guarded pages; `npm run
validate:pr` passed.
- Agent: Codex Desktop (Writing Style Guide fallback; DORI unavailable)
<!-- docs-review-head-sha: 14c334a -->
<!-- docs-review-agents-blob-sha:
3dd7c24 -->

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub — all 61 PR commits report valid
verification.
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed.
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above:
- The merged #7871/#8198/#8239 regression set passed 17 files and 407
tests.
- The Hermes cron-state, redacted-receipt, schedule, execution-ledger,
and restart-gateway-evidence regressions passed 35 focused E2E-support
tests; the controller producer suite passed 21 tests; the full
E2E-support project passed 193 files and 2,056 tests.
- The latest-main rebuild-preflight regression set passed 4 files and 27
tests.
- The final #8371 main sync passed 3 CLI files and 96 tests plus 1
integration file and 20 tests on the combined tree.
- The canonical #8372 security-rubric and Advisor contract suite passed
6 files and 70 tests.
- The production change set passed 399 files and 5,047 tests in the
earlier affected-test run; the final fixture-only delta is covered by
the exact-head focused and full E2E-support runs above.
- The merge-only target fixtures passed 50 focused tests and `npm run
typecheck:cli`.
  - `npm run checks:repository` passed.
  - `npm run validate:pr` passed on exact head `14c334aac`.
- `npm run docs` passed on exact head `14c334aac` with 0 errors and 2
existing Fern warnings; routes and generated variants are current.
- Independent exact-head maintainer, documentation-writer, nine-category
security, and cross-issue reviews passed with no findings or merge
blocker.
- [ ] Applicable broad gate passed — exact-head required CI and live E2E
remain required.
- [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) —
completed with zero errors and two Fern warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [x] New doc pages include SPDX header and frontmatter (new pages only)
— not applicable; no new documentation page was added.

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>

---------

Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants