Examples

Project management

Six levels, three rank scopes, workspace-wide tickets and sibling branches.

A workspace can contain many nested boards and cards, but ticket numbers may need to span the whole workspace. This example combines local ranks with that wider counter and shows how to return to cards to add a sibling branch.

Workspace → Project → Board → Column → Card → ChecklistItem, with Comment as a sibling branch of the checklist. Ranks restart per parent, but ticket numbers span the whole workspace. Source: tests/Zeeq.Biome.Tests/ProjectManagement.

Rank scopes and a workspace ticket counter

ProjectManagement/Domain.cs
// A new column restarts card ranks while Under(column) resumes its progression.
internal static readonly Sequence<string> CardRanks = Sequence
    .Of("a", r => r + "a")
    .PerParent();

// Ticket numbers span columns/boards/projects,
// reaching the nearest workspace ancestor.
internal static readonly Sequence<int> Tickets = Sequence
    .Of(1, n => n + 1)
    .Per<Workspace>();

// A deep ancestor supplies tenancy; a Derive
// chain supplies a title from the ticket.
internal static readonly ChildBlueprint<ProjectSeed, Column, Card> Card =
    Blueprint
        .ChildOf<ProjectSeed, Column, Card>(
            (column, ctx) =>
                new()
                {
                    Column = column,
                    Workspace = ctx.Ancestor<Workspace>(),
                    DueAt = ctx.FromNow(TimeSpan.FromDays(1)),
                }
        )
        .Derive(c => c.Rank, CardRanks)
        .Derive(c => c.Ticket, Tickets)
        .Derive(c => c.Title, (c, _) => $"Ticket {c.Ticket}");
ctx.Ancestor<Workspace>() reaches five edges up from a card's column. There's no runtime ancestor auto-creation: the chain must already contain a workspace, and the error says so when it doesn't.

A portfolio, then sibling comments

Each count multiplies the previous output. After the deepest leaves, .Under(cards) jumps back to attach comments as siblings of the checklist.

await biome
    .AddWorkspaces(out var workspaces, 2)
    .AddProjects(out _, 2) // 4 projects
    .AddBoards(out _, 1)
    .AddColumns(out var columns, 2) // 8 columns
    .AddCards(out var cards, 3) // 24 cards
    .AddChecklistItems(out var checklist, 4) // 96 deepest leaves
    .Under(cards) // comments attach to cards, not checklist items
    .AddComments(out var comments, 2)
    .BuildAsync();
The hand-written setup has three nested loops, three rank counters, and a ticket dictionary. Moving the shared rules into blueprints reduces the call site from 57 lines to 10 and gives later tests the same numbering behavior.

The real test checks that tenancy flows through every level (checklist[95].Workspace == workspaces[1]), that ranks restart (columns[2].Rank == "a", cards[3].Rank == "a"), and that all 24 × 2 comments share one frozen timestamp.

Local ranks skip explicit values; tickets span columns

ProjectManagementTests.cs
await biome
    .AddWorkspace(out _)
    .AddProject(out _)
    .AddBoard(out _)
    .AddColumns(out var columns, 2)
    .AddCards(
        out var cards,
        Cards.Blocked + Cards.Urgent,
        // Explicit "a" is reserved before the first card
        // is filled; its rank becomes "aa".
        c =>
        {
            c.Rank = "a";
            c.Title = "Regression";
        }
    )
    .AddChecklistItems(out _, 2)
    // Resume one column's rank and the encompassing workspace's ticket sequence.
    .Under(columns[0])
    .AddCard(out var next)
    .BuildAsync();

// cards[0].Rank == "aa"; cards[2].Ticket == 3
// next.Rank == "aaa"; next.Ticket == 5; next.Title == "Ticket 5"
Cards.Blocked + Cards.Urgent is one card with both traits, while the second customizer is the second card in each column. Four cards total, each column ranking its own.

A ready-made six-level branch, with a transient comment

ProjectManagementTests.cs
var time = new FakeTimeProvider(
    new DateTimeOffset(2026, 10, 11, 12, 0, 0, TimeSpan.Zero)
);
var biome = TestBiome.Start(out _, store, time);
biome.AddReadyChecklist(out var leaf);

time.Advance(TimeSpan.FromHours(2));
await biome
    .Under(leaf.Card)
    .AddComment(out var preview)
    // Built and returned, but NOT saved: this models a draft comment request.
    .Transient()
    .BuildAsync();

// store.Entities.Count == 6; no Comment saved
// preview.CreatedAt == time.GetUtcNow().AddHours(-1)