Skip to content

serialize state in two forms: single-component state.<env> and multi-component components #282

Description

@joshua-temple

Problem / why

The single in-memory component-major model must serialize back to whichever shape the manifest
declared. A single-component manifest (no components: block, one synthesized default
component) must serialize to the COLLAPSE form state.<env> so its on-disk bytes never change.
A multi-component manifest (a components: block) must serialize to the EXPAND form
state.components.<name>.<env>. The serializer picks the form from whether components are
declared.

Scope

This PR does:

  • Implement the dual serializer: collapse to state.<env> and latest_release.<single> when
    the model holds exactly the one default component (no components: block); expand to
    state.components.<name>.<env> and latest_release.components.<name> when the manifest
    declares components.
  • Make the statewrite write path carry the chosen form. The internal/statewrite overlay
    re-marshals via the model's serializer, so the form is selected once and applied on every
    retry attempt; the overlay logic itself is unchanged.
  • Guarantee byte-stable round-trips for both forms: a single-component manifest writes back
    identical state.<env> bytes; a multi-component manifest writes back stable
    state.components.<name>.<env>.

This PR does NOT:

  • Change CommitWithRetry semantics (internal/statewrite/apiwrite.go); only the Mutate
    closures select the serializer form.
  • Add per-component fan-out of promote / hotfix / rollback writes (that is P1 / R1 / R2).

Files / areas touched

  • internal/config/types.go - the dual-form serializer on the component-major model.
  • internal/config/parse.go - the serialize-back entry the statewrite path uses.
  • internal/promote/finalize.go, internal/hotfix/finalize.go,
    internal/rollback/rollback.go - select the serializer form (still single-component here).

Tests and coverage required

  • Round-trip unit tests: single-component in to component-major to single-component out is
    byte-identical; multi-component in to component-major to multi-component out is byte-stable.
  • A finalize-overlay unit test proving the single-component collapse form stays byte-stable
    through the statewrite retry loop.

Acceptance criteria

  • A single-component manifest serializes back to state.<env> byte-identically.
  • A multi-component manifest serializes to state.components.<name>.<env>.
  • The serializer chooses the form from whether components are declared; the statewrite overlay
    is unchanged.

Dependencies

Blocked by F1. Best landed with or right after F2 (so both forms have parse coverage).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions