test(e2e): enforce phase-aware onboard budgets#6732
Conversation
|
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:
📝 WalkthroughWalkthroughCold onboarding performance validation now uses calibrated root and phase-specific budgets. Trace parsing records ordered onboarding phases, evaluation reports violations, and the full-E2E test persists detailed measurements before asserting the result. ChangesCold onboard performance budgets
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant FullE2ETest
participant BudgetFile
participant OnboardTrace
participant PerformanceFixtures
FullE2ETest->>BudgetFile: Load fullE2E cold-path budget
FullE2ETest->>OnboardTrace: Capture root and phase spans
FullE2ETest->>PerformanceFixtures: Evaluate root and phase timings
PerformanceFixtures-->>FullE2ETest: Return passed and violations
FullE2ETest->>FullE2ETest: Record metrics and assert performance
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
schemas/onboard-config.schema.json (1)
8-16: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winAdd
fullE2eColdPathto the rootrequiredlist.readColdOnboardPerformanceBudget()throws when the key is missing, butschemas/onboard-config.schema.jsoncurrently allowsci/onboard-performance-budget.jsonto omit it, so the failure is deferred until the live full-e2e run.🤖 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 `@schemas/onboard-config.schema.json` around lines 8 - 16, Add fullE2eColdPath to the root required list in schemas/onboard-config.schema.json so configurations validated by the schema must include the key before readColdOnboardPerformanceBudget() processes them.
🧹 Nitpick comments (1)
test/e2e/live/full-e2e.test.ts (1)
194-222: 🚀 Performance & Scalability | 🔵 TrivialConsider validating the cold-path budget before the expensive onboarding run.
readFullE2eColdPathBudget()is only invoked here, afterinput.installand the first agent turn have already completed on the hosted runner. Ifci/onboard-performance-budget.jsonis malformed, the failure surfaces only after the full (expensive, credential-gated) cold-onboard cycle finishes. This is largely mitigated by the separate schema/unit tests catching malformed configs earlier in CI, but hoisting the budget read to the start of the test would fail fast and avoid burning a live cold-onboard run on a config typo that slipped past those checks.🤖 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/e2e/live/full-e2e.test.ts` around lines 194 - 222, Move the readFullE2eColdPathBudget() call to the beginning of the cold-path test, before input.install and the first agent turn execute, and reuse that budget for evaluateColdOnboardPerformance and the artifact output. Preserve the existing budget validation and reporting behavior while ensuring malformed configuration fails before the expensive onboarding run.
🤖 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.
Outside diff comments:
In `@schemas/onboard-config.schema.json`:
- Around line 8-16: Add fullE2eColdPath to the root required list in
schemas/onboard-config.schema.json so configurations validated by the schema
must include the key before readColdOnboardPerformanceBudget() processes them.
---
Nitpick comments:
In `@test/e2e/live/full-e2e.test.ts`:
- Around line 194-222: Move the readFullE2eColdPathBudget() call to the
beginning of the cold-path test, before input.install and the first agent turn
execute, and reuse that budget for evaluateColdOnboardPerformance and the
artifact output. Preserve the existing budget validation and reporting behavior
while ensuring malformed configuration fails before the expensive onboarding
run.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 06251a19-8860-41c8-9971-c468b8a78da6
📒 Files selected for processing (6)
ci/onboard-performance-budget.jsonschemas/onboard-config.schema.jsontest/e2e/fixtures/onboard-performance.tstest/e2e/live/full-e2e.test.tstest/e2e/support/onboard-performance.test.tstest/validate-config-schemas.test.ts
|
✨ Thanks for the test infrastructure work, @HOYALIM. Phase-aware onboard budgets will give us much clearer signal on where regressions occur. Ready for maintainer review. Related open issues: |
Signed-off-by: Ho Lim <subhoya@gmail.com>
6101706 to
db03d61
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/e2e/live/full-e2e.test.ts (1)
142-155: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winLoad the budget before the expensive turn, not after.
readFullE2eColdPathBudget()is only called at line 194, after the network-boundexecShellfirst-agent-turn call (lines 179-191, bounded byFIRST_TURN_TIMEOUT_MS) has already completed. Ifci/onboard-performance-budget.jsonis missing or invalid, the test still pays for that round trip before discovering the config error. Since the budget read/validation is cheap and independent of the timed cold-onboard window, hoist it to the top ofassertColdOnboardPerformance(or even beforereadAndDeleteTraceWindow) to fail fast on bad config.♻️ Proposed reordering
): Promise<void> { + const budget = readFullE2eColdPathBudget(); const traceWindow = readAndDeleteTraceWindow(input.traceFile, input.traceDirectory); ... const totalMs = Date.now() - traceWindow.startedAtMs; const totalSecs = Math.ceil(totalMs / 1_000); - const budget = readFullE2eColdPathBudget(); const performance = evaluateColdOnboardPerformance(traceWindow, totalMs, budget);Also applies to: 192-195
🤖 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/e2e/live/full-e2e.test.ts` around lines 142 - 155, Move the readFullE2eColdPathBudget() call to the beginning of assertColdOnboardPerformance, before readAndDeleteTraceWindow and the network-bound execShell first-agent-turn operation. Preserve the existing budget validation and later use, ensuring missing or invalid configuration fails before the timed cold-onboard work starts.
🤖 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/e2e/live/full-e2e.test.ts`:
- Around line 142-155: Move the readFullE2eColdPathBudget() call to the
beginning of assertColdOnboardPerformance, before readAndDeleteTraceWindow and
the network-bound execShell first-agent-turn operation. Preserve the existing
budget validation and later use, ensuring missing or invalid configuration fails
before the timed cold-onboard work starts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 86af9247-7a1a-4100-a18a-d657020107f6
📒 Files selected for processing (6)
ci/onboard-performance-budget.jsonschemas/onboard-config.schema.jsontest/e2e/fixtures/onboard-performance.tstest/e2e/live/full-e2e.test.tstest/e2e/support/onboard-performance.test.tstest/validate-config-schemas.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- schemas/onboard-config.schema.json
- test/e2e/support/onboard-performance.test.ts
- ci/onboard-performance-budget.json
- test/validate-config-schemas.test.ts
- test/e2e/fixtures/onboard-performance.ts
cjagwani
left a comment
There was a problem hiding this comment.
Reviewed exact head db03d61. Exact-head live runs alone will not make this approval-ready:
-
Schema/runtime mismatch: schemas/onboard-config.schema.json:8-16 does not require fullE2eColdPath, and test/validate-config-schemas.test.ts:284-298 explicitly accepts its absence. Runtime unconditionally requires it and also enforces postOnboardBudgetMs <= totalBudgetMs (onboard-performance.ts:63-96), while schema accepts both invalid states. Align schema and runtime, including the cross-field constraint.
-
Diagnostics are numerically false: independently rounding both sides upward at onboard-performance.ts:170-187 reports 1501ms > 1500ms as '2s exceeds 2s' and the test codifies it. Report milliseconds or enough precision.
-
The interval label is false: full-e2e.test.ts:179-195 starts totalMs at the onboard root during installer step 3, excluding steps 1-2, while lines 245-248 call it '[1/8]-to-first-response'. The post-onboard component also includes installer finalization before the turn. Rename/measure the actual boundaries.
-
#6660 calibration is unproven. The new 185s sandbox cap is simply 205s-20s with no multi-sample current-main sandbox-phase distribution, percentile, or runner-variance evidence; sandbox+post consumes the full total while ignoring other phases, so this is not the documented decomposition. Supply durable current-main phase calibration and derive the thresholds from it.
Also bind accepted phase spans to the one root: validate trace ID/parentage/status/timestamps/root containment and duration consistency. The current scope+name lookup accepts foreign, failed, out-of-window phases. Parse/validate the budget before starting the costly cloud flow. After fixes and adversarial tests, run exact-head cloud-onboard, full-e2e, and Advisor.
- Require fullE2eColdPath in onboard-config schema; update schema tests - Report violations in milliseconds to avoid rounded-equal strings like '2s exceeds 2s' - Fix interval label from [1/8]-to-first-response to onboard-root-to-first-response - Read budget before expensive cloud operations so bad config fails fast - Reduce sandbox cap from 185s to 180s to leave headroom for other phases - Document 180s as provisional pending cold-path CI phase measurements Fixes cjagwani blockers 1-4 from PR NVIDIA#6732 review.
Collapsed the two-test block for the fullE2eColdPath schema requirement into a single it() to stay within the 1500-line default budget limit.
|
/ok to test 2d0c3f9 |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
test/e2e/live/full-e2e.test.ts (1)
200-234: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLocal
performancevariable shadows the globalperformanceobject.
const performance = evaluateColdOnboardPerformance(...)shadows Node's built-inperf_hooks.performanceglobal for the rest of the function. It's harmless today sinceDate.now()is used for timing elsewhere in this scope, but it's a footgun if someone later reaches forperformance.now()inside this function and instead silently gets the evaluation result object.♻️ Suggested rename
- const performance = evaluateColdOnboardPerformance( + const performanceEvaluation = evaluateColdOnboardPerformance( traceWindow, firstTurnCompletedAtMs, input.budget, ); const rootStartToFirstTurnCompletionSecs = Math.ceil( - performance.rootStartToFirstTurnCompletionMs / 1_000, + performanceEvaluation.rootStartToFirstTurnCompletionMs / 1_000, );(and update the remaining
performance.*references at lines 222, 225, 232-234, 258-260 accordingly)🤖 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/e2e/live/full-e2e.test.ts` around lines 200 - 234, Rename the local result from evaluateColdOnboardPerformance in the current test function to avoid shadowing the global performance object, and update all references to its rootStartToFirstTurnCompletionMs, rootEndToFirstTurnCompletionMs, passed, and violations properties accordingly.
🤖 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/onboard/machine/handlers/gateway.test.ts`:
- Around line 126-150: Update the test around TRACE_FILE_ENV to save its
existing process.env value before overriding it, then restore that saved value
in the finally block instead of always deleting the variable. Preserve deletion
only when no prior value existed, and keep the existing resetTraceForTests
cleanup.
In `@test/e2e/fixtures/onboard-performance.ts`:
- Around line 178-186: Filter spans by summaryTraceId before collecting roots or
enforcing uniqueness in the span-processing loop. Update the logic around
ONBOARD_ROOT_SPAN and ONBOARD_PHASE_NAME_SET so only records belonging to the
summarized trace can be added to roots or phases; preserve the existing
duplicate validation for that trace.
In `@test/onboard-performance-config-schema.test.ts`:
- Around line 26-45: Update the CalibrationSample model and calibration
assertions to record each sample’s commit SHA, rather than relying only on the
global measurementHeadSha. Capture the SHA when creating each sample and verify
every sample matches the expected exact-head SHA, including the related
assertions around the sample validation flow.
- Line 200: Update the assertion for sample.measurementsMs.phases in the
onboarding performance config schema test to compare phase keys without
requiring insertion order, such as by comparing order-independent key
collections. Preserve validation that the expected phase names are present while
removing representation-order dependence.
---
Nitpick comments:
In `@test/e2e/live/full-e2e.test.ts`:
- Around line 200-234: Rename the local result from
evaluateColdOnboardPerformance in the current test function to avoid shadowing
the global performance object, and update all references to its
rootStartToFirstTurnCompletionMs, rootEndToFirstTurnCompletionMs, passed, and
violations properties accordingly.
🪄 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: 0b4ad74a-0968-4342-86a2-6998f93ddc3d
📒 Files selected for processing (11)
ci/full-e2e-cold-path-calibration.jsonci/onboard-performance-budget.jsonschemas/onboard-config.schema.jsonscripts/validate-configs.tssrc/lib/onboard/machine/handlers/gateway.test.tssrc/lib/onboard/machine/handlers/gateway.tstest/e2e/fixtures/onboard-performance.tstest/e2e/live/full-e2e.test.tstest/e2e/support/onboard-performance.test.tstest/onboard-performance-config-schema.test.tstest/validate-config-schemas.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- test/e2e/support/onboard-performance.test.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
…into fix/6732-cjagwani-blockers
|
/ok to test ab66cf0 |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@test/e2e/support/onboard-performance.test.ts`:
- Around line 1-12: Add the `@module-tag` e2e/credential-free marker at the top of
the onboard-performance test module, before the existing imports, so the test is
classified as credential-free.
🪄 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: d364b55a-d2a2-4003-bf50-2b005abd93cd
📒 Files selected for processing (12)
ci/full-e2e-cold-path-calibration.jsonci/onboard-performance-budget.jsonci/source-shape-test-budget.jsonschemas/onboard-config.schema.jsonscripts/validate-configs.tssrc/lib/onboard/machine/handlers/gateway.test.tssrc/lib/onboard/machine/handlers/gateway.tstest/e2e/fixtures/onboard-performance.tstest/e2e/live/full-e2e.test.tstest/e2e/support/onboard-performance.test.tstest/onboard-performance-config-schema.test.tstest/validate-config-schemas.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- ci/full-e2e-cold-path-calibration.json
- test/onboard-performance-config-schema.test.ts
- src/lib/onboard/machine/handlers/gateway.ts
- schemas/onboard-config.schema.json
- ci/onboard-performance-budget.json
- test/validate-config-schemas.test.ts
- test/e2e/fixtures/onboard-performance.ts
@prekshivyas, there was an error processing your request: See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/ |
|
/ok to test b32673a |
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
🤖 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 `@test/e2e/support/onboard-performance.test.ts`:
- Around line 1-12: Add the `@module-tag` e2e/credential-free marker at the top of
the onboard-performance test module, before the existing imports, so the test is
classified as credential-free.
🪄 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: d364b55a-d2a2-4003-bf50-2b005abd93cd
📒 Files selected for processing (12)
ci/full-e2e-cold-path-calibration.jsonci/onboard-performance-budget.jsonci/source-shape-test-budget.jsonschemas/onboard-config.schema.jsonscripts/validate-configs.tssrc/lib/onboard/machine/handlers/gateway.test.tssrc/lib/onboard/machine/handlers/gateway.tstest/e2e/fixtures/onboard-performance.tstest/e2e/live/full-e2e.test.tstest/e2e/support/onboard-performance.test.tstest/onboard-performance-config-schema.test.tstest/validate-config-schemas.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- ci/full-e2e-cold-path-calibration.json
- test/onboard-performance-config-schema.test.ts
- src/lib/onboard/machine/handlers/gateway.ts
- schemas/onboard-config.schema.json
- ci/onboard-performance-budget.json
- test/validate-config-schemas.test.ts
- test/e2e/fixtures/onboard-performance.ts
🛑 Comments failed to post (1)
test/e2e/support/onboard-performance.test.ts (1)
1-12: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash sed -n '1,15p' test/e2e/support/onboard-performance.test.tsRepository: NVIDIA/NemoClaw
Length of output: 743
🏁 Script executed:
sed -n '1,120p' test/e2e/support/onboard-performance.test.ts && printf '\n--- SEARCH ---\n' && rg -n "`@module-tag`|credential-free" test/e2e/support/onboard-performance.test.tsRepository: NVIDIA/NemoClaw
Length of output: 4271
Add the credential-free module tag
test/e2e/support/onboard-performance.test.tsshould include@module-tag e2e/credential-freeat the top so it’s treated as a credential-free E2E test.🤖 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/e2e/support/onboard-performance.test.ts` around lines 1 - 12, Add the `@module-tag` e2e/credential-free marker at the top of the onboard-performance test module, before the existing imports, so the test is classified as credential-free.Source: Path instructions
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
b32673a to
e5944ab
Compare
|
/ok to test e5944ab |
|
@coderabbitai review |
✅ Action performedReview finished.
|
PR Review Advisor — InformationalAdvisor assessment: Informational / low confidence E2E guidanceAdvisory only: coverage and selector recommendations are non-authoritative. E2E / PR Gate independently computes and dispatches trusted jobs without consuming this output. Recommended coverage:
1 optional coverage item · 1 optional selector · 0 new-test recommendations
This is an automated, non-authoritative review. Findings are inputs to maintainer adjudication. Warnings and optional suggestions do not require a response or follow-up. A human maintainer makes the final merge decision. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/machine/handlers/gateway.test.ts (1)
103-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTernary-as-statement for side effects risks a
no-unused-expressionslint failure.The restore/delete logic correctly fixes the previously flagged issue (env var is now captured and restored instead of unconditionally deleted). However, using a bare ternary expression as a statement (lines 104-106) is flagged as incorrect by ESLint's
no-unused-expressionsrule under its default options (allowTernary: false), even when both branches are function calls. If this repo's ESLint config doesn't setallowTernary: true, this pattern will fail lint. Anif/elseis more idiomatic here and avoids the risk entirely.♻️ Suggested fix
} finally { - previousTraceFile === undefined - ? Reflect.deleteProperty(process.env, TRACE_FILE_ENV) - : Reflect.set(process.env, TRACE_FILE_ENV, previousTraceFile); + if (previousTraceFile === undefined) { + delete process.env[TRACE_FILE_ENV]; + } else { + process.env[TRACE_FILE_ENV] = previousTraceFile; + } resetTraceForTests(); fs.rmSync(directory, { recursive: true, force: true }); }Based on learnings, this mirrors the previously suggested fix for restoring
TRACE_FILE_ENV, which used plaindelete/assignment rather thanReflect. Confirm whetherno-unused-expressions/allowTernaryis configured for this repo before deciding whether to adjust.🤖 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/onboard/machine/handlers/gateway.test.ts` around lines 103 - 106, Replace the bare ternary side-effect statement in the finally cleanup with an explicit if/else: delete TRACE_FILE_ENV when previousTraceFile is undefined, otherwise restore it to the captured value. Keep the existing previousTraceFile handling and environment restoration behavior unchanged.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.
Nitpick comments:
In `@src/lib/onboard/machine/handlers/gateway.test.ts`:
- Around line 103-106: Replace the bare ternary side-effect statement in the
finally cleanup with an explicit if/else: delete TRACE_FILE_ENV when
previousTraceFile is undefined, otherwise restore it to the captured value. Keep
the existing previousTraceFile handling and environment restoration behavior
unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 25647ca0-4df3-4afb-8d48-3fb721a0d20d
📒 Files selected for processing (1)
src/lib/onboard/machine/handlers/gateway.test.ts
|
/ok to test 29238dc |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@cjagwani Ready for exact-head re-review at Every item from the change request is covered:
Latest automated-review items were also adjudicated:
Exact-head evidence:
The remaining Please re-review this exact head and clear the prior change request if satisfied. |
|
/ok to test |
@cjagwani, there was an error processing your request: See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/1/ |
## Summary Replace the SHA-copying E2E no-secret exception workflow with a repository-native protected-environment approval on the exact `E2E / PR Gate` run. Maintainers can use GitHub's **Review deployments** button while the controller preserves the existing exact-diff, role, risk-plan, and stale-revision checks. ## Changes - Publish allowlisted exception mode, PR, head SHA, and base SHA outputs from the trusted coordinator, then wait on `e2e-no-secret-exception` with `deployment: false` and no secret references or PR-controlled execution. - Read the workflow run's approval history, require one approval for only that environment, derive the reviewer and optional bounded comment from GitHub, recheck `maintain`/`admin`, and reuse the existing exact-diff resolver. An absent or unprotected environment fails closed. - Bind approval to the trusted first workflow attempt, exact workflow SHA, current PR revision, matching failed check, recomputed risk plan, and a final live-PR read. Per-PR concurrency cancels stale waiting approvals. - Keep the typed `workflow_dispatch` resolver for rollout and rerun fallback because GitHub approval history is run-scoped rather than attempt-scoped. The controller exception and workflow contract tests protect both paths. - Update the E2E reference and maintainer merge-gate guidance, including the required repository environment configuration. This addresses the maintainer friction observed on #6732 without adding a GitHub App. ## 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: No end-user product behavior changed; maintainer workflow and E2E reference documentation were updated. - [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: Adversarial review covered approval provenance, first-attempt replay prevention, permissions, unconfigured-environment failure, stale revisions, and exact check identity; no actionable findings. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes the DCO sign-off declaration 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 — `npx vitest run --project integration test/pr-e2e-gate.test.ts test/pr-e2e-gate-lifecycle.test.ts test/pr-e2e-gate-exceptions.test.ts test/pr-e2e-gate-workflow.test.ts` (4 files, 88 tests passed) - [ ] Applicable broad gate passed — not applicable; this focused workflow/controller change is covered by the targeted suite and normal hooks. - [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) — not applicable; no `docs/` pages changed. - [ ] 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: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an approval-based “no-secret” workflow step to resolve eligible E2E gate exceptions. * Gate completions now include a linked run “details” URL and standardized exception outputs. * **Documentation** * Updated maintainer guidance for protected-environment approval setup and the typed manual fallback path. * **Tests** * Expanded end-to-end coverage for approval validation, strict trust/scoping checks, concurrency wiring, and improved gate output assertions (including rerun rejection and safe input handling). <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Replace the opaque full-E2E wall-clock assertion with a calibrated, phase-aware cold-onboard performance gate. The gate measures the actual onboard-root and first-turn boundaries, validates all trace evidence against the summarized root, and retains the existing functional, silence, and BuildKit assertions.
Related Issue
Closes #6660.
Changes
max(5s, 10%)headroom, rounded up to one second.Calibration Evidence
Measurement head:
4544d07c8bfd500c3b64a74380ef5cd0e62089f5Verification
npm run check:diff(includes config validation, source-shape, test-size, typecheck, commit lint, and security/lint hooks)cloud-onboard,credential-sanitization,security-posture,full-e2e,onboard-repair, andonboard-resume: run 29289301062Signed-off-by: Ho Lim subhoya@gmail.com
Summary by CodeRabbit