[rush reporter][R6A] Add bootstrap handoff and compatibility adapters - #5993
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Create the authoritative frontend reporter host before version selection, register global reporter controls, and preserve legacy output unless a non-legacy reporter is explicitly selected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Consume the repository experiment before Rush version selection, keep agent detection out of pre-major defaults, strip frontend-only controls before engine handoff, and preserve legacy verbosity compatibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
|
Independent Fixed in
Verified the minimal zero-dependency prelude, 1 MiB bounded buffering, 64 KiB UTF-8-safe external-output chunks, required-overflow failure, truncation marker, exclusive nonce/path handoff with owner-only permissions, ordered npm capture, replay/delete/retention cleanup, direct invocation, no-opt-in legacy behavior, and no R5 operation-rendering, Heft, or Rush 6 default-flip scope. The old-engine stderr bridge remains intentional to preserve machine-reporter stdout purity; default/no-opt-in output bypasses it and remains unchanged. Validation completed: focused Stack remains intentionally linear with child auto-merge disabled. Required retarget order after each predecessor merges: #5985 -> retarget #5986 to |
|
Combined deep review of current head
|
Stop reporter control scans at the pass-through separator and add an exactly-once frontend close contract across success, failure, and termination paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Keep reporter controls out of ts-command-line globals, gate incompatible engines before initialization, and enforce bounded signal and close-error behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Preserve unsupported custom reporter values until frontend ownership is unambiguous, and narrow emergency legacy stripping to the reporter selection flag. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Probe reporter ownership without requiring a value, then enforce strict reporter parsing only after frontend ownership is established. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
2b8d8e5 to
c1e13cd
Compare
|
Fixed all five bootstrap review findings in c1e13cd.
Validation: deterministic bootstrap generation; reporter build and 299 tests; rush-lib build and 774 tests; Rush frontend build and 62 tests; |
Preserve the complete R6 side history and acceptance corrections on the qualified main67ca R3A parent. Reconcile startup-envelope version metadata with incoming native-private fields and retain the original side tests plus a public-path regression. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
fe52c2d to
9c40269
Compare
Document both the typed event sink and the frontend-assigned sessionId in the cross-version handoff without changing its shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Share separated-value recognition with stripping so valueless controls cannot consume legacy flags, and use debug only as the unrequested primary file log-level default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Consume --verbose only for known actions that do not define it and parse repository opt-in value controls only when they are not command-owned. Preserve native aliases, declared custom values, unresolved plugin namespaces, and pass-through arguments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Keep the original R3A producer channel and documentation fix while carrying both frontend-owned value and flag stripping lists from the final foundation parent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Preserve the exact R6 lifecycle, handoff and legacy compatibility contracts while propagating the final command-aware foundation controls and handoff documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Preserve the standalone flag strip list alongside consumed value controls in both real bootstrap compatibility fallback paths. Keep this combined-boundary fix on the corrected review baseline, outside the scoped 6019 follow-up delta. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Preserve the exact published R2B slice and review corrections while reconciling native private members and replacing unbranded parser test objects with real execution paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Share separated-value recognition with stripping so valueless controls cannot consume legacy flags, and use debug only as the unrequested primary file log-level default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Consume --verbose only for known actions that do not define it and parse repository opt-in value controls only when they are not command-owned. Preserve native aliases, declared custom values, unresolved plugin namespaces, and pass-through arguments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Retain the exact scoped producer API and WeakMap-backed plugin facades while preserving native-private parser/plugin members and real launch-boundary coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Document both the typed event sink and the frontend-assigned sessionId in the cross-version handoff without changing its shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
7abfad2 to
47d4f36
Compare
Reconcile the six frontend conflicts with the published R6 content while inheriting the pinned parent's private build-tooling and publishing changes. Preserve the original R6 scope and API, serialized lifecycle and cleanup, and both real bootstrap fallback control-ownership regressions. The merge retains fa7553d as first parent and 47d4f36 as second parent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Compose R6 initialization cleanup and bootstrap compatibility with the landed core's canonical full-detail log and frontend ownership. Preserve both histories and keep the main-relative change within the published R6 scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Machine-readable stdout can be corrupted or suppressed, and a filesystem path is misclassified as public.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 2
New issues introduced by this change (3)
| Severity | Finding |
|---|---|
apps/rush/src/RushCommandSelector.ts — When stdout is machine-owned, renderLive is false. adapter.capture() synchronously invokes the… View comment |
|
libraries/rush-lib/src/scripts/InstallRunRushBootstrap.ts — This stdout decision ignores --output=...://stdout. For example, the supported `--reporter=file… View comment |
|
apps/rush/src/RushVersionSelector.ts — This message embeds expectedRushPath, but #reportStartupMessage classifies every emitted event… View comment |
What changed in this PR
Adds reporter-aware bootstrap handoff, bounded npm-output capture, cross-version compatibility adapters, and lifecycle cleanup.
Changes:
- Introduces nonce-protected bootstrap replay and retention cleanup.
- Bridges legacy engine output into reporter events.
- Strengthens reporter shutdown and initialization cleanup.
| File | Description |
|---|---|
libraries/rush-lib/webpack.config.js |
Injects the bootstrap Rush version. |
libraries/rush-lib/src/utilities/test/npmrcUtilities.test.ts |
Tests privacy metadata handling. |
libraries/rush-lib/src/utilities/npmrcUtilities.ts |
Adds log privacy classifications. |
libraries/rush-lib/src/scripts/test/InstallRunScripts.test.ts |
Tests npm output capture. |
libraries/rush-lib/src/scripts/test/InstallRunRushBootstrap.test.ts |
Tests bootstrap handoff behavior. |
libraries/rush-lib/src/scripts/InstallRunRushBootstrap.ts |
Implements bootstrap buffering and handoff. |
libraries/rush-lib/src/scripts/install-run.ts |
Captures ordered npm output. |
libraries/rush-lib/src/scripts/install-run-rush.ts |
Integrates bootstrap initialization. |
libraries/rush-lib/src/scripts/generated/BootstrapProtocol.ts |
Adds generated handoff constants. |
libraries/rush-lib/src/api/Rush.ts |
Exposes reporter protocol compatibility metadata. |
libraries/reporter/src/test/ReporterHost.test.ts |
Expands replay and cleanup tests. |
libraries/reporter/src/test/PlaintextReporter.test.ts |
Tests rendered-output suppression. |
libraries/reporter/src/test/Manager.test.ts |
Tests lifecycle concurrency and delivery. |
libraries/reporter/src/test/Compatibility.test.ts |
Updates adapter compatibility tests. |
libraries/reporter/src/reporters/PlaintextReporter.ts |
Avoids duplicate rendered output. |
libraries/reporter/src/manager/ReporterManager.ts |
Serializes cleanup and protected delivery. |
libraries/reporter/src/index.ts |
Exports legacy fallback output types. |
libraries/reporter/src/frontend/ReporterHost.ts |
Adds replay fallback and retention cleanup. |
libraries/reporter/src/compat/OldEngineOutputAdapter.ts |
Records whether output was rendered. |
libraries/reporter/src/bootstrap/BootstrapProtocol.ts |
Extends generated protocol content. |
libraries/reporter/README.md |
Documents cleanup and logging behavior. |
common/reviews/api/rush-reporter.api.md |
Updates the public API report. |
common/changes/@rushstack/rush-reporter/review-r6-shared-close_2026-09-09-14-10.json |
Records shared-close changes. |
common/changes/@rushstack/rush-reporter/review-r6-cleanup_2026-09-09-13-00.json |
Records cleanup changes. |
common/changes/@rushstack/rush-reporter/copilot-reporter-r6a-bootstrap-handoff_2026-08-28-04-40.json |
Records fallback-output changes. |
common/changes/@microsoft/rush/review-r6-cleanup_2026-09-09-13-00.json |
Records frontend cleanup changes. |
common/changes/@microsoft/rush/review-base-control-composition_2026-09-10.json |
Records control-stripping compatibility. |
common/changes/@microsoft/rush/copilot-reporter-r6a-bootstrap-handoff_2026-08-28-04-40.json |
Records bootstrap handoff support. |
apps/rush/src/test/RushReporterHost.test.ts |
Tests frontend replay and cleanup. |
apps/rush/src/test/RushFrontend.test.ts |
Tests frontend compatibility metadata. |
apps/rush/src/test/RushCommandSelector.test.ts |
Tests old-engine output bridging. |
apps/rush/src/RushVersionSelector.ts |
Reports version-selection activity. |
apps/rush/src/RushReporterHost.ts |
Replays handoffs and handles fallback. |
apps/rush/src/RushFrontend.ts |
Passes reporter compatibility state. |
apps/rush/src/RushCommandSelector.ts |
Adapts old and incompatible engines. |
apps/rush/src/IRushFrontendLaunchOptions.ts |
Adds reporter launch metadata. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Preserve machine reporter writes during legacy capture, recognize owned additional stdout outputs during bootstrap without claiming custom parameters, and classify version installation paths as local-sensitive. Keep legacy defaults and canonical full-detail logging unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10


Part of #5979.
Stack
Base:
main. All Reporter core prerequisites, including #5989 and #5988, have landed. The main-relative diff remains exactly 36 R6 paths. Bootstrap replay, compatibility, retention and initialization cleanup compose with the landed canonical unfiltered debug log. Parallel Heft, AI qualification and later follow-up features are not imported.Merge remains gated on current-head CI and independent approval.
Design choice
Use a minimal prelude in the existing generated
install-run-rushpath rather than add a reporter-specific script variant. This keeps every existing bootstrap entry point and update mechanism intact, uses the frozen zero-dependency encoder/protocol major from #5986, and gates all changed visible behavior behind an explicit reporter request or the repository experiment.The prelude parses only early reporter/log-level controls plus the comment-aware
useRushReporterexperiment. It incrementally builds a 1 MiB bounded NDJSON buffer, chunks external output at 64 KiB, preserves required records, evicts only replaceable activity status, appends the RFC truncation marker, and fails if required output cannot be retained. npm stdout/stderr are captured as ordered framed records with a hard capture ceiling and persistent UTF-8 decoding.The handoff is written under the OS temp directory with owner-only permissions where supported, an exclusive filename, and a nonce duplicated in private path/nonce environment variables. The frontend creates the authoritative host before version selection, replays then deletes the file, clears the private environment, and sweeps abandoned files using the existing retention policy.
Compatibility behavior
rush-lib; explicit protocol-major incompatibility fails with an update/use-legacy diagnostic.externalOutputevents without contaminating machine-reporter stdout.LegacyFallbackSink/legacy rendering behavior.rushinvocation has no handoff and converges on the same authoritative frontend host used by bootstrap invocation.Current landing qualification (September 11, 2026)
Published
67ac6545cad54d2234d4c723686c09c5a023661apreserves the former R6 head and landedmain@130daa8as its two parents. Normal consumer build/types/lint/API and 392 focused Linux tests passed, including full-debug canonical logs under file/normal, physical-close failures, initialization cleanup and concurrent shutdown. New hosted CI and human approval are still required.Earlier validation (pre-landing snapshot)
node libraries/reporter/scripts/generateBootstrapProtocol.js --checknode common/scripts/install-run-rush.js test --only @rushstack/rush-reporter --only @microsoft/rush-lib --only @microsoft/rushinstall-runnpm-capture smoke test usingcowsay@1.6.0(ordered stdout/stderr frames, no overflow)node common/scripts/install-run-rush.js checknode common/scripts/install-run-rush.js change --verify --no-fetchgit diff --checkFocused coverage includes direct/bootstrap startup, replay/deletion, invalid path/nonce, missing/unreadable handoffs, permissions, abandoned cleanup, truncation and required overflow, ordered external output, UTF-8 boundaries, unsupported explicit requests, implicit fallback, and old/new frontend-engine combinations.
Rollback
Revert this single commit. The optional hooks in
install-rundisappear with the prelude, and the default no-opt-in bootstrap/legacy path remains the unchanged fallback throughout the rollout.Non-goals
StreamCollator