Problem / why
cascade should run promote / version / release / hotfix over ONE internal model regardless of
how the manifest is written. The first step is a pure-internal component-major model: a
manifest with no components: block loads as a single synthesized default component, all in
memory, with ZERO change to the on-disk shape, the generated output, or any behavior. This is
invisible to users and de-risks the later multi-component work by exercising the component
dimension behind the existing single-component surface.
This is the foundation root issue. It carries no schema change and no expectation risk because
nothing observable changes.
Scope
This PR does:
- Introduce a typed in-memory component-major container that the rest of the code reads
through, for example a *ManifestState wrapping Components map[string]map[string]*EnvState
(component name to environment name to EnvState), plus accessors (get-or-create
components[name][env], ComponentNames()).
- On load, synthesize a single
default component from the top-level
builds / deploys / environments / triggers / tag_prefix and re-key the environment
state under components.default.<env> IN MEMORY only.
- Keep the on-disk shape, the serializer output, and all generated workflows byte-identical:
for a single-component manifest, serialization still emits state.<env> (the collapse form,
fully specified in F3; this PR may stub the collapse so round-trip stays byte-stable).
- Re-point the in-memory reads in
internal/promote, internal/hotfix, internal/rollback,
internal/orchestrate, and internal/version to go through the default component via the
accessors.
This PR does NOT:
- Add any
components: parsing (F2) or the dual serializer's expand form (F3).
- Change any on-disk bytes or generated output.
- Add a
components: user surface (V1).
Files / areas touched
internal/config/types.go - the in-memory container and accessors.
internal/config/parse.go - synthesize default on load.
internal/promote/, internal/hotfix/, internal/rollback/, internal/orchestrate/,
internal/version/ - read state through the default component.
Tests and coverage required
- Unit tests on the accessors (get-or-create nested entry, component enumeration).
- A round-trip test: a single-component manifest loads into the component-major model and
serializes back byte-identically to its input.
- The existing promote / hotfix / rollback / version / orchestrate unit tests pass unchanged.
Acceptance criteria
- All state reads go through the component dimension via the
default component.
- A single-component manifest round-trips byte-identically (load to component-major, serialize
back to state.<env>).
- No generated workflow output changes.
Dependencies
None within the epic. It is the root foundation issue.
Problem / why
cascade should run promote / version / release / hotfix over ONE internal model regardless of
how the manifest is written. The first step is a pure-internal component-major model: a
manifest with no
components:block loads as a single synthesizeddefaultcomponent, all inmemory, with ZERO change to the on-disk shape, the generated output, or any behavior. This is
invisible to users and de-risks the later multi-component work by exercising the component
dimension behind the existing single-component surface.
This is the foundation root issue. It carries no schema change and no expectation risk because
nothing observable changes.
Scope
This PR does:
through, for example a
*ManifestStatewrappingComponents map[string]map[string]*EnvState(component name to environment name to
EnvState), plus accessors (get-or-createcomponents[name][env],ComponentNames()).defaultcomponent from the top-levelbuilds/deploys/environments/triggers/tag_prefixand re-key the environmentstate under
components.default.<env>IN MEMORY only.for a single-component manifest, serialization still emits
state.<env>(the collapse form,fully specified in F3; this PR may stub the collapse so round-trip stays byte-stable).
internal/promote,internal/hotfix,internal/rollback,internal/orchestrate, andinternal/versionto go through thedefaultcomponent via theaccessors.
This PR does NOT:
components:parsing (F2) or the dual serializer's expand form (F3).components:user surface (V1).Files / areas touched
internal/config/types.go- the in-memory container and accessors.internal/config/parse.go- synthesizedefaulton load.internal/promote/,internal/hotfix/,internal/rollback/,internal/orchestrate/,internal/version/- read state through thedefaultcomponent.Tests and coverage required
serializes back byte-identically to its input.
Acceptance criteria
defaultcomponent.back to
state.<env>).Dependencies
None within the epic. It is the root foundation issue.