# Bank Composition Middleware and Staged Editing Decision

Status: Decided
Cycle: 2026-03
Domain Owner: `docs/studio`
Cross-Domain Impact: `docs/packer`

## Context

`Bank Composition` needs a section-scoped coordinator above the new UI components because:

- `StudioDualListView<T>` is intentionally dumb;
- `StudioAssetCapacityMeter` is intentionally dumb;
- the section must follow the same staged-edit model already used elsewhere in `Asset Details`;
- capacity and blocker rules differ by asset family.

The current codebase already has a staged-edit primitive in:

- [`StudioFormSession.java`](../../../prometeu-studio/src/main/java/p/studio/controls/forms/StudioFormSession.java)

The earlier `Bank Composition` decisions already fixed:

- DTO projection:
  [`Bank Composition Details DTO Projection Decision.md`](./Bank%20Composition%20Details%20DTO%20Projection%20Decision.md)
- base components:
  [`Bank Composition Base Components Decision.md`](./Bank%20Composition%20Base%20Components%20Decision.md)
- section shell:
  [`Bank Composition Section Shell Decision.md`](./Bank%20Composition%20Section%20Shell%20Decision.md)

This decision closes the middleware direction discussed in:

- [`Agenda-04-Asset-Bank-Composition-Middleware-and-Staged-Editing.md`](../agendas/Agenda-04-Asset-Bank-Composition-Middleware-and-Staged-Editing.md)

## Decision

Adopt a dedicated bank-composition section-scoped coordinator built around `StudioFormSession<BankCompositionDraft>`.

The first-wave rules are:

1. `StudioFormSession<BankCompositionDraft>` is the shared staged-edit core for the section;
2. `Bank Composition` must not introduce a second session model parallel to `StudioFormSession`;
3. family-specific variation must not come from subclassing `StudioFormSession`;
4. family-specific variation must come from draft factories and bank-composition policies offered per asset family;
5. `apply` may remain stubbed or disabled until persistence is wired, but the session contract should already exist.

The section-scoped coordinator owns orchestration around the form session, including:

- translating persisted section state into session source/draft state;
- beginning edit mode;
- resetting draft state;
- canceling edits;
- applying draft state when persistence is available;
- evaluating transfer eligibility;
- evaluating reorder effects;
- calculating capacity state;
- calculating hard-limit blockers and hints.

The section-scoped coordinator should publish one section-facing view model that includes:

- shell state such as editing mode, dirty state, and action availability;
- left and right list state;
- capacity-meter state;
- blockers and hint text when relevant.

## Justification

This is the simplest design that matches the actual codebase.

`StudioFormSession` already provides the staged-edit lifecycle the section needs.
Creating a second coordinator-specific session model would duplicate behavior for no gain.

At the same time, subclassing `StudioFormSession` is the wrong variation point.
The current class is final, and more importantly the lifecycle does not change by asset family.
What changes by family is bank-composition logic: draft shaping, eligibility, capacity, and blockers.

That makes policies and factories the correct seam.

## Invariants and Constraints

The following constraints now apply:

1. `StudioFormSession<BankCompositionDraft>` is the only staged-edit core for the section in the first wave;
2. asset-family differences must be modeled outside `StudioFormSession`;
3. the section-scoped coordinator remains section-specific and should not become a platform-wide bank manager abstraction;
4. dumb UI components consume derived state and do not own bank rules;
5. the section-facing output must be consolidated into one view model rather than scattered state channels.

## Explicit Non-Decisions

This decision does not yet define:

- the exact Java class names or package layout for the section-scoped coordinator, policies, or draft factories;
- the exact shape of `BankCompositionDraft`;
- the `workspaceBus` event contract;
- persistence/apply integration with packer;
- the exact text of family-specific hint and blocker messages.

## Propagation Targets

- Studio agendas:
  [`Agenda-05-Asset-Bank-Composition-WorkspaceBus-Interaction.md`](../agendas/Agenda-05-Asset-Bank-Composition-WorkspaceBus-Interaction.md)
  [`Agenda-06-Asset-Bank-Composition-Persistence-and-Snapshot-Propagation.md`](../agendas/Agenda-06-Asset-Bank-Composition-Persistence-and-Snapshot-Propagation.md)
- Studio specs:
  [`4. Assets Workspace Specification.md`](../specs/4.%20Assets%20Workspace%20Specification.md)
- Studio code:
  `StudioFormSession` integration, `Bank Composition` section-scoped coordinator, family-specific draft factories, and family-specific bank-composition policies

## Validation Notes

Examples implied by this decision:

- a tile family and a sound family can share the same `StudioFormSession` lifecycle while using different capacity/blocker policies;
- the dual list and meter can stay dumb because the section-scoped coordinator supplies already-derived state;
- when persistence is not wired yet, `beginEdit`, `reset`, and `cancel` still work through the shared form-session model.
