Core writes one Set per element for a non-empty composite and never touches the container's own address.
The sink writes each element through place into elementSlot/memberSlot, both of which only find-or-append.
Nothing in Set or Commit removes sequence positions past the last one written, or mapping keys the dump did not write, so a mapped composite is left partly stale.
Reproduction
File holds:
ferry.Dump of config{Tags: []string{"x"}} returns nil and leaves:
ferry.Load[config] then returns Tags:[x b c].
The same holds for mappings: dumping Limits: map[string]int{"a": 5} over limits: {a: 1, b: 2} leaves b: 2 in place, and it loads back.
Both legs are silent.
The rules it breaks
The Sink doc on the same file says a save replaces "the keys your struct maps", and the stale entries sit under a key the struct maps.
ADR-0001's driver-fidelity guarantee says Dump then Load returns the value dumped, and here it does not.
No test in driver/yaml covers a dump whose composite is shorter than the one already in the file, and ferrytest.RoundTrip always dumps onto a fresh plane, so nothing catches it.
Anchored at driver/yaml/sink.go:167, commit fc8707c.
Severity: high. Reproduced end to end.
Core writes one
Setper element for a non-empty composite and never touches the container's own address.The sink writes each element through
placeintoelementSlot/memberSlot, both of which only find-or-append.Nothing in
SetorCommitremoves sequence positions past the last one written, or mapping keys the dump did not write, so a mapped composite is left partly stale.Reproduction
File holds:
ferry.Dumpofconfig{Tags: []string{"x"}}returns nil and leaves:ferry.Load[config]then returnsTags:[x b c].The same holds for mappings: dumping
Limits: map[string]int{"a": 5}overlimits: {a: 1, b: 2}leavesb: 2in place, and it loads back.Both legs are silent.
The rules it breaks
The
Sinkdoc on the same file says a save replaces "the keys your struct maps", and the stale entries sit under a key the struct maps.ADR-0001's driver-fidelity guarantee says Dump then Load returns the value dumped, and here it does not.
No test in
driver/yamlcovers a dump whose composite is shorter than the one already in the file, andferrytest.RoundTripalways dumps onto a fresh plane, so nothing catches it.Anchored at
driver/yaml/sink.go:167, commit fc8707c.Severity: high. Reproduced end to end.