fix(headless): S7 report why a multi-session process never attaches the console
A configured process with 2+ sessions and --console silently skipped console attachment (the plan's "single-session only for the first cut"), indistinguishable from --console simply having worked. Report it explicitly through the same HeadlessDiagnosticWriter.Message stream every other structured event already uses. TwoSessionsWithConsoleFlagReportsSingleSessionOnly was shown to fail against the silent-skip branch (mutation: the else-branch body removed) -- the diagnostics stream carried only the ordinary lifecycle/resource JSON lines, with no "single-session only" message anywhere. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
2ff1e1228c
commit
314cb5f4a5
2 changed files with 60 additions and 0 deletions
|
|
@ -192,6 +192,14 @@ internal sealed class HeadlessProcessHost : IDisposable
|
|||
};
|
||||
console = controller;
|
||||
}
|
||||
else if (consoleEnabled)
|
||||
{
|
||||
// S7 (2026-09-07 review round): a silent skip here read as
|
||||
// "--console worked" to an operator with no way to tell
|
||||
// otherwise — the launcher's multi-session mode is a
|
||||
// legitimate, common configuration, so say so explicitly.
|
||||
_diagnostics.Message("console", "single-session only");
|
||||
}
|
||||
_console = console;
|
||||
_consoleRendererSubscription = consoleRendererSubscription;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,6 +564,58 @@ public sealed class HeadlessConsoleTests
|
|||
Assert.Equal(expectDimmed, text.Contains("[2m"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// S7: a multi-session process with <c>--console</c> must tell the
|
||||
/// operator why the console never attached (the launcher's multi-session
|
||||
/// mode is a legitimate, common configuration) instead of silently
|
||||
/// doing nothing — see <c>HeadlessDiagnosticWriter.Message</c>'s "console"
|
||||
/// category.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void TwoSessionsWithConsoleFlagReportsSingleSessionOnly()
|
||||
{
|
||||
// StandardInput credentials (one line per session, consumed by
|
||||
// HeadlessCredentialResolver BEFORE the console reader thread ever
|
||||
// starts — see HeadlessProcessHost's own constructor comment) avoid
|
||||
// needing an ACE-shaped Environment credential just to reach the
|
||||
// console-wiring branch this test targets.
|
||||
HeadlessSessionDescriptor StandardInputDescriptor(string id) =>
|
||||
Descriptor() with
|
||||
{
|
||||
Id = id,
|
||||
Credential = new HeadlessCredentialReference
|
||||
{
|
||||
Provider = HeadlessCredentialProviderKind.StandardInput,
|
||||
Reference = "fixture",
|
||||
},
|
||||
};
|
||||
var configuration = new HeadlessConfiguration
|
||||
{
|
||||
Version = 1,
|
||||
Sessions =
|
||||
[
|
||||
StandardInputDescriptor("one"),
|
||||
StandardInputDescriptor("two"),
|
||||
],
|
||||
};
|
||||
var operations = new FixtureSessionOperations();
|
||||
using var diagnostics = new StringWriter();
|
||||
using var input = new System.IO.StringReader(
|
||||
"password-one" + Environment.NewLine
|
||||
+ "password-two" + Environment.NewLine);
|
||||
using var host = new HeadlessProcessHost(
|
||||
configuration,
|
||||
HeadlessPathSet.Resolve(new HeadlessPathOverrides()),
|
||||
input,
|
||||
diagnostics,
|
||||
operations,
|
||||
new FakeTimeProvider(),
|
||||
directCredentials: null,
|
||||
consoleEnabled: true);
|
||||
|
||||
Assert.Contains("single-session only", diagnostics.ToString());
|
||||
}
|
||||
|
||||
private static bool WaitForEndOfInput(HeadlessConsoleController controller) =>
|
||||
controller.Reader.EndOfInput.Wait(TimeSpan.FromSeconds(5));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue