fix(headless): N5 dim only lifecycle/command/portal lines

HeadlessConsoleRenderer dimmed every line uniformly, so chat and
interface text (player-visible content) read the same washed-out weight
as scheduling/session-status noise like "entered world" or "command
rejected: ...". Only lifecycle, command, and portal lines are scheduling
noise; chat and interface text now print at the terminal's default
weight.

ChatAndInterfaceTextPrintAtDefaultWeightNeverDimmed was shown to fail
against the prior dim-everything WriteLine (mutation: dim parameter not
yet threaded through, every call still unconditionally wrapped in the
ANSI dim/reset pair) -- the chat line and interface text both carried
the dim escape sequence.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-07 08:13:24 +02:00
parent 70e86c180e
commit e3639a4c18
2 changed files with 96 additions and 13 deletions

View file

@ -365,6 +365,72 @@ public sealed class HeadlessConsoleTests
Assert.Equal(expected, HeadlessConsoleChatFormatter.Format(entry));
}
// ── HeadlessConsoleRenderer: N5 dim-weight rules ─────────────────────
/// <summary>
/// N5: chat and interface text are player-visible content, not
/// scheduling noise — they must print at the terminal's default weight,
/// never dimmed, even when color is enabled.
/// </summary>
[Fact]
public void ChatAndInterfaceTextPrintAtDefaultWeightNeverDimmed()
{
var output = new StringWriter();
var renderer = new HeadlessConsoleRenderer(output, useColor: true);
var entry = new RuntimeChatEntry(
Revision: 1,
SenderGuid: 0x50000010u,
Kind: (int)ChatKind.LocalSpeech,
Sender: "Bob",
Text: "hi",
ChannelName: string.Empty);
renderer.OnChat(new RuntimeChatDelta(default, entry));
renderer.WriteInterfaceText("Unknown command: /x");
string text = output.ToString();
Assert.DoesNotContain("[2m", text);
Assert.Contains("[Local] Bob: hi", text);
Assert.Contains("Unknown command: /x", text);
}
/// <summary>
/// N5: lifecycle, command, and portal lines are scheduling/session-
/// status noise, not player-visible content — dimmed when color is
/// enabled.
/// </summary>
[Fact]
public void LifecycleCommandAndPortalLinesAreDimmedWhenColorIsEnabled()
{
var output = new StringWriter();
var renderer = new HeadlessConsoleRenderer(output, useColor: true);
renderer.OnLifecycle(new RuntimeLifecycleDelta(
default, RuntimeLifecycleState.Starting, RuntimeLifecycleState.InWorld));
renderer.OnCommand(new RuntimeCommandDelta(
default, RuntimeCommandDomain.Chat, 0, RuntimeCommandStatus.Rejected, Text: "boom"));
renderer.OnPortal(new RuntimePortalDelta(
default,
new RuntimePortalSnapshot(
Generation: 1,
RuntimePortalKind.Portal,
Readiness: new RuntimeDestinationReadiness(
1, 0x12345678u, false, false, 0, true, true, true),
Materialized: true,
Completed: false,
Cancelled: false,
WorldViewportObserved: true,
WorldSimulationAvailable: true,
InvariantFailureCount: 0,
WaitCueShown: false,
PortalMaterializationCount: 1)));
string[] lines = output.ToString()
.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
Assert.Equal(3, lines.Length);
Assert.All(lines, line => Assert.Contains("[2m", line));
}
// ── HeadlessSessionHost.SubmitConsoleLine: the real dispatch pipeline ─
[Fact]