Skip to content

[rush reporter][R6A] Add bootstrap handoff and compatibility adapters - #5993

Open
Sean Larkin (TheLarkInn) wants to merge 52 commits into
copilot/reporter-r3a-session-sinkfrom
copilot/reporter-r6a-bootstrap-handoff
Open

[rush reporter][R6A] Add bootstrap handoff and compatibility adapters#5993
Sean Larkin (TheLarkInn) wants to merge 52 commits into
copilot/reporter-r3a-session-sinkfrom
copilot/reporter-r6a-bootstrap-handoff

Conversation

@TheLarkInn

Copy link
Copy Markdown
Member

Part of #5979.

Stack

graph LR
  M[main] --> R1A[#5985 R1A package wiring]
  R1A --> R1B[#5986 R1B bootstrap generation]
  R1B --> R2A[#5987 R2A experiment config]
  R2A --> R2B[#5989 R2B frontend host controls]
  R2B --> R6A[This PR: R6A bootstrap handoff]
Loading

Base: copilot/reporter-r2b-frontend-host-controls. This PR intentionally contains only the R6A delta relative to #5989 and does not enable auto-merge while the stack ancestors remain open.

Design choice

Use a minimal prelude in the existing generated install-run-rush path 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 useRushReporter experiment. 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

  • No explicit or repository opt-in: the existing bootstrap logger, inherited npm output, and legacy Rush rendering are unchanged.
  • Explicit unsupported reporter/log-level requests fail before loading rush-lib; explicit protocol-major incompatibility fails with an update/use-legacy diagnostic.
  • Implicit environment detection does not enable the pre-major path. Repository opt-in safely falls back to legacy for an older frontend or incompatible handoff, replaying bounded raw fallback output instead of losing it.
  • New frontend + old engine: legacy engine output remains visible on stderr and is bridged as ordered externalOutput events without contaminating machine-reporter stdout.
  • Old frontend + new engine: the engine receives no host sink and retains the existing LegacyFallbackSink/legacy rendering behavior.
  • Direct rush invocation has no handoff and converges on the same authoritative frontend host used by bootstrap invocation.

Validation

  • node libraries/reporter/scripts/generateBootstrapProtocol.js --check
  • node common/scripts/install-run-rush.js test --only @rushstack/rush-reporter --only @microsoft/rush-lib --only @microsoft/rush
  • Built webpack install-run npm-capture smoke test using cowsay@1.6.0 (ordered stdout/stderr frames, no overflow)
  • node common/scripts/install-run-rush.js check
  • node common/scripts/install-run-rush.js change --verify --no-fetch
  • git diff --check

Focused 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-run disappear with the prelude, and the default no-opt-in bootstrap/legacy path remains the unchanged fallback throughout the rollout.

Non-goals

  • R5 operation rendering or replacing StreamCollator
  • Heft child protocol/problem matcher integration
  • agent auto-selection or the Rush 6 default flip
  • removing legacy terminal APIs, rendering, or fallback behavior

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
@TheLarkInn

Sean Larkin (TheLarkInn) commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

Independent /pr-agentmerge review completed against #5979 and RFC sections 4.3, 5.5, and 8.

Fixed in 2b8d8e5ede:

  • unsupported required bootstrap records now fail explicit reporter requests and trigger ordered legacy fallback for repository opt-in;
  • authenticated handoff files are deleted and private environment variables are cleared when frontend selection or reporter initialization fails before replay;
  • both older and newer structured engine protocol-major mismatches now fail explicit requests or receive a LegacyFallbackSink for implicit fallback, rather than an incompatible live manager sink.

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 @rushstack/rush-reporter, @microsoft/rush, and @microsoft/rush-lib tests/builds; bootstrap generation check; rush check; rush change --verify --no-fetch; and git diff --check.

Stack remains intentionally linear with child auto-merge disabled. Required retarget order after each predecessor merges: #5985 -> retarget #5986 to main -> retarget #5987 to main -> retarget #5989 to main -> retarget #5993 to main. At each step, verify the slice-only diff, full CI, and reviews before advancing. Current external gate: #5985 is mergeable with green checks and auto-merge enabled, but still requires approval; the #5986 Windows Node 26 rerun is still pending. No review threads exist on #5993.

@TheLarkInn

Copy link
Copy Markdown
Member Author

Combined deep review of current head 2b8d8e5ede.

  1. HIGH bootstrap events classify full argv and cwd as public. Omit them or use non-public classified values.
  2. HIGH the old-engine adapter writes captured stdout back to stderr. Restore each stream to itself.
  3. MEDIUM npm install output is captured but not shown live, so long installs appear frozen. Tee while capturing.
  4. MEDIUM bootstrap reporter parsing repeats the pass-through -- bug. Stop scanning at the separator.
  5. MEDIUM rush.json discovery and version resolution occur outside the friendly error handler, producing raw stack traces. Move them inside the guarded path.

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
@TheLarkInn
Sean Larkin (TheLarkInn) force-pushed the copilot/reporter-r6a-bootstrap-handoff branch from 2b8d8e5 to c1e13cd Compare August 28, 2026 16:40
@TheLarkInn

Copy link
Copy Markdown
Member Author

Fixed all five bootstrap review findings in c1e13cd.

  • Removed argv and cwd from public bootstrap events and sanitized reporter-mode invocation output.
  • Preserved stdout and stderr separation for old engines, including async output, cleanup, machine-readable stdout, and hard-exit delivery.
  • Teed npm output live to the correct streams while retaining ordered handoff records without duplicate visible replay.
  • Stopped reporter control parsing at standalone -- and preserved pass-through arguments.
  • Moved rush.json discovery and Rush version resolution into the friendly guarded error path.

Validation: deterministic bootstrap generation; reporter build and 299 tests; rush-lib build and 774 tests; Rush frontend build and 62 tests; rush check; stacked rush change --verify; slice-only diff. Rebased the three R6 commits directly onto 62d9e7a. Auto-merge remains disabled. Ready for review.

The newly rerun CI for #5989 exposed the existing reporter-package change without its release note. Describe the already-implemented pass-through separator behavior; no runtime code or gate changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
@TheLarkInn
Sean Larkin (TheLarkInn) force-pushed the copilot/reporter-r3a-session-sink branch from c8637e5 to e3bf1e7 Compare September 7, 2026 18:46
Only the existing R2B reporter change note is new content; all runtime and test blobs are unchanged. Preserve both parent histories and verify the child feature patch exactly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Follow up #5987 without changing configuration behavior; concurrent flag-file tests empty api/test/temp.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
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
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
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
The newly rerun CI for #5989 exposed the existing reporter-package change without its release note. Describe the already-implemented pass-through separator behavior; no runtime code or gate changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
@TheLarkInn
Sean Larkin (TheLarkInn) force-pushed the copilot/reporter-r3a-session-sink branch from e3bf1e7 to d57e66b Compare September 7, 2026 20:07
Preserve the existing feature history and scope after the backed-up native stack root alignment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10

@TheLarkInn Sean Larkin (TheLarkInn) left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

R6 acceptance review against #5979 and the referenced handoff cleanup/retention contract.

Comment thread apps/rush/src/RushReporterHost.ts
Comment thread apps/rush/src/RushReporterHost.ts
Apply emergency legacy selection before strict reporter validation, preserve custom command controls, and honor canonical stdout/stderr destinations without treating them as paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
Preserve R6 merge ancestry and bootstrap/legacy-engine compatibility while incorporating corrected foundation controls and reserved-stream ownership.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Replay a48ce82416c7e3e6711763feffaf3efa8f1c6d4b while preserving corrected foundation stream ownership tests and limiting README changes to the six-line R6 cleanup paragraph.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Inject the partial-initialization fixture through ReporterManager's existing initializer so the test replays onto the original R6 slice without importing a later host manager option.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Replay cad7bfdd3a4296f647718844d72b8583413c1313 without introducing the later _flushAndConfirmAsync API or expanding the six-line R6 README addition.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Reserve the existing per-entry lifecycle tail for disposal while retaining raw failures for AggregateError reporting. Concurrent normal shutdown now waits behind a blocked disposal flush before sharing the cached close operation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
Import the existing reporter types and manager explicitly on the owning R6 slice; no later host API is introduced. Validated frontend, manager, bootstrap, capture and retention suites on the corrected R6 parent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4747f826-8c83-495d-80df-3d1168662e10
@TheLarkInn
Sean Larkin (TheLarkInn) force-pushed the copilot/reporter-r3a-session-sink branch from d57e66b to fe52c2d Compare September 9, 2026 16:03
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
@TheLarkInn
Sean Larkin (TheLarkInn) force-pushed the copilot/reporter-r3a-session-sink branch from fe52c2d to 9c40269 Compare September 10, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs triage

Development

Successfully merging this pull request may close these issues.

1 participant