feat(headless): FA6 — role-discriminated policy + the fellowship/allegiance
two-bot gate Adds the infrastructure docs/plans/2026-08-11-fellowship-allegiance-campaign.md D8 and docs/research/2026-08-11-fa-acdream-seams.md §6.2 call for: - HeadlessBotPolicyDescriptor gains an optional typed Role (HeadlessBotPolicyRole.Leader/Recruit) so two sessions selecting the SAME policy id run different scripts — fellowship leader/allegiance patron vs fellowship recruit/allegiance vassal. - HeadlessBotPolicyFactory.Create widens from Create(string id) to Create(HeadlessBotPolicyDescriptor, GameRuntime) — the gate policies need RuntimeFriendlyTargetQuery, which (like its RuntimeHostileTargetQuery sibling) takes the concrete GameRuntime rather than the narrower IGameRuntimeView a policy's own Tick receives (IRuntimeEntityView's snapshot carries no name/PWD-bitfield). The single call site (HeadlessSessionHost.cs) already has the constructed runtime in scope, so no new constructor parameter or cross-session coordinator was needed. - FellowshipAllegianceLeaderBotPolicy / FellowshipAllegianceRecruitBotPolicy: a full stage-machine pair covering proximity (retail's admin @teleallto — "teleport everyone online to me" — needs no cross-session name sharing, unlike @teleto <name>; D8's proximity requirement is load-bearing, recruit fails without it), fellowship create+recruit, the D4 0x00A6 panel-open declaration with a vitals-presence assertion, the decisive two-session assertions (the RECRUIT bot's own RuntimeFellowshipState/ RuntimeAllegianceState flipping — not the Leader's local echo), a mid-flow reconnect on both bots proving FA2's reset-and-reseed semantics over the real wire, and teardown (disband / break) with matching decisive-clear assertions. Every pre-FA6 policy (idle, lifecycle-smoke, observer-movement, portal-route-smoke, jump-probe) is unaffected; the widened factory signature is the only touch point. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6b8e29cde6
commit
2825589035
3 changed files with 850 additions and 4 deletions
|
|
@ -94,6 +94,31 @@ internal sealed class HeadlessBotPolicyDescriptor
|
|||
{
|
||||
[JsonRequired]
|
||||
public string Id { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Campaign FA slice FA6: optional role discriminator for a policy that
|
||||
/// coordinates two bots run from the SAME process config (e.g. the
|
||||
/// fellowship/allegiance gate's Leader — fellowship leader AND
|
||||
/// allegiance patron — vs Recruit — fellowship recruit AND allegiance
|
||||
/// vassal, docs/research/2026-08-11-fa-acdream-seams.md §6.2). Ignored
|
||||
/// by every policy id that doesn't need it (all five pre-FA6 policies);
|
||||
/// <see cref="AcDream.Headless.Policies.HeadlessBotPolicyFactory.Create"/>
|
||||
/// rejects a missing role for a policy id that requires one.
|
||||
/// </summary>
|
||||
public HeadlessBotPolicyRole? Role { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>See <see cref="HeadlessBotPolicyDescriptor.Role"/>.</summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter<HeadlessBotPolicyRole>))]
|
||||
internal enum HeadlessBotPolicyRole
|
||||
{
|
||||
/// <summary>Fellowship leader / allegiance patron — creates the
|
||||
/// fellowship, recruits the Recruit bot, and receives its oath.</summary>
|
||||
Leader,
|
||||
|
||||
/// <summary>Fellowship recruit / allegiance vassal — gets recruited and
|
||||
/// swears to the Leader bot.</summary>
|
||||
Recruit,
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter<HeadlessCredentialProviderKind>))]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue