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
|
|
@ -1,8 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using AcDream.App.Configuration;
|
||||
using AcDream.App.Rendering.Residency;
|
||||
using AcDream.App.Streaming;
|
||||
using AcDream.Runtime.Session;
|
||||
|
||||
namespace AcDream.App;
|
||||
|
||||
|
|
@ -62,7 +65,34 @@ public sealed record RuntimeOptions(
|
|||
string? VulkanDeviceOverride,
|
||||
string? VulkanForcedUnsupportedFeature,
|
||||
bool VulkanCapabilityProbe,
|
||||
int VulkanCapabilityProbeFrames)
|
||||
int VulkanCapabilityProbeFrames,
|
||||
/// <summary>Campaign LA slice LA1: the raw <c>--session-config</c> path,
|
||||
/// or <see langword="null"/> when the flag was not supplied (the env-var
|
||||
/// dev flow). Kept for diagnostics/logging only.</summary>
|
||||
string? SessionConfigPath,
|
||||
/// <summary>Campaign LA slice LA1: the configured session's id, used as
|
||||
/// the <c>sessionId</c> field on every status-stream event. Defaults to
|
||||
/// <c>"app"</c> at every call site when unset (env-var flow).</summary>
|
||||
string? SessionId,
|
||||
/// <summary>Campaign LA slice LA1: the session-config character
|
||||
/// selector, or <see langword="null"/> for today's existing
|
||||
/// first-available fallback (absent selector = LA7's char-select screen
|
||||
/// stop point once that slice lands; this slice does not build the
|
||||
/// screen).</summary>
|
||||
LiveSessionCharacterSelector? LiveCharacterSelector,
|
||||
/// <summary>Campaign LA slice LA1: absolute path for the status-event
|
||||
/// JSONL stream. <see langword="null"/> = no writer constructed.</summary>
|
||||
string? StatusFilePath,
|
||||
/// <summary>Campaign LA slice LA1: plugin ids to load.
|
||||
/// <see langword="null"/> = load every discovered plugin (today's
|
||||
/// behavior). Consumed by LA5; parsed and carried now.</summary>
|
||||
IReadOnlyList<string>? Plugins,
|
||||
/// <summary>Campaign LA slice LA1: ordered chat-typed strings run once
|
||||
/// entered-world. Consumed by LA6; parsed and carried now.</summary>
|
||||
IReadOnlyList<string> LoginCommands,
|
||||
/// <summary>Campaign LA slice LA1: inter-command delay for
|
||||
/// <see cref="LoginCommands"/>, milliseconds.</summary>
|
||||
int LoginCommandDelayMs)
|
||||
{
|
||||
/// <summary>
|
||||
/// Build options from the process environment. Used by
|
||||
|
|
@ -170,9 +200,72 @@ public sealed record RuntimeOptions(
|
|||
// closes the window. Zero -- unset, unparseable, or an explicit 0 --
|
||||
// keeps the interactive behaviour, so no existing invocation changes.
|
||||
VulkanCapabilityProbeFrames:
|
||||
TryParseNonNegativeInt(env("ACDREAM_VULKAN_PROBE_FRAMES")) ?? 0);
|
||||
TryParseNonNegativeInt(env("ACDREAM_VULKAN_PROBE_FRAMES")) ?? 0,
|
||||
// Campaign LA slice LA1: the env-var dev flow never carries a
|
||||
// session-config document — every new field below stays at its
|
||||
// "nothing configured" default. RuntimeOptions.FromSessionConfig
|
||||
// overlays the real values on top of this base.
|
||||
SessionConfigPath: null,
|
||||
SessionId: null,
|
||||
LiveCharacterSelector: null,
|
||||
StatusFilePath: null,
|
||||
Plugins: null,
|
||||
LoginCommands: [],
|
||||
LoginCommandDelayMs: 500);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Campaign LA slice LA1: builds options for the <c>--session-config</c>
|
||||
/// launch path. Starts from the same env-var parse as
|
||||
/// <see cref="FromEnvironment"/> (diagnostic/dev flags are still
|
||||
/// env-controlled — only the LIVE session settings and the five new LA1
|
||||
/// fields come from the document) and overlays the resolved session.
|
||||
/// <paramref name="resolvedPassword"/> is revealed into
|
||||
/// <see cref="LivePass"/> exactly as wide as the existing env-var flow —
|
||||
/// see that field's own doc.
|
||||
/// </summary>
|
||||
internal static RuntimeOptions FromSessionConfig(
|
||||
string datDir,
|
||||
Func<string, string?> env,
|
||||
string sessionConfigPath,
|
||||
SessionConfiguration config,
|
||||
SessionDescriptor session,
|
||||
string? resolvedPassword)
|
||||
{
|
||||
if (config is null) throw new ArgumentNullException(nameof(config));
|
||||
if (session is null) throw new ArgumentNullException(nameof(session));
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(sessionConfigPath);
|
||||
|
||||
RuntimeOptions baseOptions = Parse(datDir, env);
|
||||
SessionContentDescriptor? content = config.Process?.Content;
|
||||
return baseOptions with
|
||||
{
|
||||
PreparedAssetPath = NullIfEmpty(content?.PreparedAssetPath)
|
||||
?? baseOptions.PreparedAssetPath,
|
||||
LiveMode = true,
|
||||
LiveHost = session.Endpoint.Host,
|
||||
LivePort = session.Endpoint.Port,
|
||||
LiveUser = session.Account,
|
||||
LivePass = resolvedPassword,
|
||||
SessionConfigPath = sessionConfigPath,
|
||||
SessionId = session.Id,
|
||||
LiveCharacterSelector = MapCharacterSelector(session.Character),
|
||||
StatusFilePath = NullIfEmpty(session.StatusFile),
|
||||
Plugins = session.Plugins,
|
||||
LoginCommands = (IReadOnlyList<string>?)session.LoginCommands ?? [],
|
||||
LoginCommandDelayMs = session.LoginCommandDelayMs,
|
||||
};
|
||||
}
|
||||
|
||||
private static LiveSessionCharacterSelector? MapCharacterSelector(
|
||||
SessionCharacterSelectorDescriptor? selector) =>
|
||||
selector is null
|
||||
? null
|
||||
: new LiveSessionCharacterSelector(
|
||||
selector.Index,
|
||||
selector.Id,
|
||||
selector.Name);
|
||||
|
||||
/// <summary>True iff live-mode credentials are present and valid for connecting.</summary>
|
||||
public bool HasLiveCredentials =>
|
||||
LiveMode && !string.IsNullOrEmpty(LiveUser) && !string.IsNullOrEmpty(LivePass);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue