Решили: завести IGuildRosterView — интерфейс в сборке Guildmaster.Guild, реализованный ProfileService из Guildmaster.Game. Через него забег читает людей дома и сажает их на боевые места. Сам дом основывается сразу с отрядом: CreateGuild рождает столько «Сосудов», сколько выходит в бой.

Почему: RosterSlot.VesselId был пуст у всех, а GuildState.Roster создавался пустым — то есть людей в игре не существовало вовсе, и экран отряда показывал бы восемь свободных мест.

  • Метод в IProfileService отвергнут: профиль объявлен в Guildmaster.Core, а VesselState и GuildState живут в Guildmaster.Guild. Отдать ростер через профиль значило бы затащить типы дома в ядро — заплатить слоями за одно свойство.
  • Копии людей в RunState отвергнуты: человек durable и принадлежит дому, он переживает поход и копит Летопись. Копия в забеге дала бы одному человеку двух владельцев, и первый же наём посреди забега развёл бы их.
  • Люди при основании дома, а не на старте забега (решение Макса 22.08.2026): дом с людьми копит Летопись с первого дня, а пустой дом до первого похода — это просто отложенный тот же код.

Грабли: зависимость забега от дома опциональна, и это не небрежность. Дев-пути и тесты поднимают RunStateService без дома вовсе; при живой обязательной зависимости они падали бы на конструкторе. Без дома забег стартует с пустыми местами — видно на экране, и это честнее, чем выдуманные бойцы: игрок повёл бы в бой тех, кого в его гильдии нет.

Сид рождения выводится из id дома и порядкового номера: один дом всегда рождает одних и тех же людей, два дома — разных. Хранится сид, не собранная строка.

Владелец правды: Scripts/Guild/IGuildRosterView.cs, Scripts/Game/Services/ProfileService.cs, тесты RosterCompositionTests.NewRun_SeatsGuildPeople_OnBattlePlacesOnly и NewRun_WithoutGuild_LeavesPlacesEmpty.