docs: Campaign LA — pinned launch-contract schema COMMITTED into plan LA1
The LA3 Opus review process note was right: the contract both sides implement lived only in orchestrator prompts, which is exactly the drift mode the pin exists to prevent (and it produced the paths-key CRITICAL). The schema, field rules, probe-mode discriminator, and status vocabulary are now a binding plan section; amendments change this text first, implementations second. Ledger: LA3 fix round dispatched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
0bcc7ba3a3
commit
db9ad53c1c
38 changed files with 2397 additions and 40 deletions
|
|
@ -0,0 +1,148 @@
|
|||
using AcDream.App;
|
||||
using AcDream.App.Configuration;
|
||||
using AcDream.Runtime.Session;
|
||||
|
||||
namespace AcDream.App.Tests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Campaign LA slice LA1: round-trip tests for
|
||||
/// <see cref="RuntimeOptions.FromSessionConfig"/> — the overlay that turns a
|
||||
/// parsed <see cref="SessionConfiguration"/>/<see cref="SessionDescriptor"/>
|
||||
/// into the same typed bundle the env-var dev flow produces.
|
||||
/// </summary>
|
||||
public sealed class RuntimeOptionsSessionConfigTests
|
||||
{
|
||||
[Fact]
|
||||
public void SessionConfigOverridesLiveSettingsAndCarriesAllFiveNewFields()
|
||||
{
|
||||
var config = new SessionConfiguration { Version = 1 };
|
||||
var session = new SessionDescriptor
|
||||
{
|
||||
Id = "gui-session",
|
||||
Endpoint = new SessionEndpointDescriptor
|
||||
{
|
||||
Host = "192.168.1.50",
|
||||
Port = 9123,
|
||||
},
|
||||
Account = "guiaccount",
|
||||
Character = new SessionCharacterSelectorDescriptor { Name = "GuiToon" },
|
||||
Credential = new SessionCredentialDescriptor
|
||||
{
|
||||
Provider = SessionCredentialProviderKind.Environment,
|
||||
Reference = "IGNORED",
|
||||
},
|
||||
Plugins = ["PluginA", "PluginB"],
|
||||
LoginCommands = ["/tell x, hi"],
|
||||
LoginCommandDelayMs = 900,
|
||||
StatusFile = "status.jsonl",
|
||||
};
|
||||
|
||||
RuntimeOptions options = RuntimeOptions.FromSessionConfig(
|
||||
"D:\\dat",
|
||||
_ => null,
|
||||
"session.json",
|
||||
config,
|
||||
session,
|
||||
"resolved-password");
|
||||
|
||||
Assert.True(options.LiveMode);
|
||||
Assert.Equal("192.168.1.50", options.LiveHost);
|
||||
Assert.Equal(9123, options.LivePort);
|
||||
Assert.Equal("guiaccount", options.LiveUser);
|
||||
Assert.Equal("resolved-password", options.LivePass);
|
||||
Assert.Equal("session.json", options.SessionConfigPath);
|
||||
Assert.Equal("gui-session", options.SessionId);
|
||||
Assert.Equal(
|
||||
new LiveSessionCharacterSelector(null, null, "GuiToon"),
|
||||
options.LiveCharacterSelector);
|
||||
Assert.Equal("status.jsonl", options.StatusFilePath);
|
||||
Assert.Equal(["PluginA", "PluginB"], options.Plugins);
|
||||
Assert.Equal(["/tell x, hi"], options.LoginCommands);
|
||||
Assert.Equal(900, options.LoginCommandDelayMs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AbsentCharacterSelectorLeavesFirstAvailableFallbackInEffect()
|
||||
{
|
||||
var config = new SessionConfiguration { Version = 1 };
|
||||
var session = new SessionDescriptor
|
||||
{
|
||||
Id = "no-selector",
|
||||
Endpoint = new SessionEndpointDescriptor { Host = "127.0.0.1", Port = 9000 },
|
||||
Account = "account",
|
||||
Credential = new SessionCredentialDescriptor
|
||||
{
|
||||
Provider = SessionCredentialProviderKind.Environment,
|
||||
Reference = "X",
|
||||
},
|
||||
};
|
||||
|
||||
RuntimeOptions options = RuntimeOptions.FromSessionConfig(
|
||||
"D:\\dat",
|
||||
_ => null,
|
||||
"session.json",
|
||||
config,
|
||||
session,
|
||||
"password");
|
||||
|
||||
Assert.Null(options.LiveCharacterSelector);
|
||||
Assert.Null(options.Plugins);
|
||||
Assert.Empty(options.LoginCommands);
|
||||
Assert.Equal(500, options.LoginCommandDelayMs);
|
||||
Assert.Null(options.StatusFilePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProcessContentOverridesDatDirectoryAndPreparedAssetPath()
|
||||
{
|
||||
var config = new SessionConfiguration
|
||||
{
|
||||
Version = 1,
|
||||
Process = new SessionProcessSettings
|
||||
{
|
||||
Content = new SessionContentDescriptor
|
||||
{
|
||||
DatDirectory = "D:\\configured-dats",
|
||||
PreparedAssetPath = "D:\\configured-dats\\acdream.pak",
|
||||
},
|
||||
},
|
||||
};
|
||||
var session = new SessionDescriptor
|
||||
{
|
||||
Id = "content-session",
|
||||
Endpoint = new SessionEndpointDescriptor { Host = "127.0.0.1", Port = 9000 },
|
||||
Account = "account",
|
||||
Credential = new SessionCredentialDescriptor
|
||||
{
|
||||
Provider = SessionCredentialProviderKind.Environment,
|
||||
Reference = "X",
|
||||
},
|
||||
};
|
||||
|
||||
RuntimeOptions options = RuntimeOptions.FromSessionConfig(
|
||||
"D:\\configured-dats",
|
||||
_ => null,
|
||||
"session.json",
|
||||
config,
|
||||
session,
|
||||
"password");
|
||||
|
||||
Assert.Equal(
|
||||
"D:\\configured-dats\\acdream.pak",
|
||||
options.PreparedAssetPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnvironmentFlowLeavesEveryNewFieldAtItsNothingConfiguredDefault()
|
||||
{
|
||||
RuntimeOptions options = RuntimeOptions.Parse("D:\\dat", _ => null);
|
||||
|
||||
Assert.Null(options.SessionConfigPath);
|
||||
Assert.Null(options.SessionId);
|
||||
Assert.Null(options.LiveCharacterSelector);
|
||||
Assert.Null(options.StatusFilePath);
|
||||
Assert.Null(options.Plugins);
|
||||
Assert.Empty(options.LoginCommands);
|
||||
Assert.Equal(500, options.LoginCommandDelayMs);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue