1 parent
e08467bf38
commit
2a47be454d
17 files changed
+849
-855
No files matched your search
@@ -1,66 +0,0 @@
|
||||
# Config audit and TOML migration
|
||||
|
||||
This branch updates only lixenwraith/config. It uses Go 1.27.1 and the user's merged
|
||||
TOML main commit `b59d068ff6a48b86365a65e1121343f672f77a67`, pinned as
|
||||
`v0.0.0-20260928180512-b59d068ff6a4` because no version tag existed at integration.
|
||||
Logwisp adoption and other TOML consumers are separate follow-up work.
|
||||
|
||||
## Confirmed defects and fixes
|
||||
|
||||
| Finding | Result | Regression evidence |
|
||||
| --- | --- | --- |
|
||||
| Fractions/overflow could pass through weak numeric conversion | Checked TOML conversion and explicit destination-width parsing | `TestCheckedConversionsAndRollback`, `FuzzConfigNumericConversions` |
|
||||
| Options, input containers and returned values could alias caller state | Owned options/values and detached reads/clones | `TestOptionsAreOwned`, `TestOwnedValuesAndSnapshots` |
|
||||
| Updating the cached target changed old AsStruct results | Immutable cached result and a fresh snapshot per call | `TestOwnedValuesAndSnapshots` |
|
||||
| ExportEnv compared uncomparable slices/maps directly | Deep equality, with callbacks outside Config locks | `TestExportEnvContainerValues` |
|
||||
| Invalid sources could be published before decoding failed | Whole-source validation before mutation | `TestSourceReplacementIsTransactional` |
|
||||
| Removed env/CLI values survived subsequent loads | Successful loads replace their complete source | `TestSourceReplacementIsTransactional` |
|
||||
| A timed-out reload kept running and could publish after stop | Context, watcher identity, path and generation checked at commit | `TestReloadCannotPublishAfterStopTimeoutOrNewLoad` |
|
||||
| A timeout could suppress retries of unchanged content | Retry timeouts while deduplicating their notifications | `TestWatcherRetriesTimedOutUnchangedContent` |
|
||||
| Debounce did not cover errors from partial in-place writes | Errors and successful updates wait for a quiet interval | `TestWatcherDebouncesErrorsAndRecovers` |
|
||||
| Metadata-only polling missed some replacements/edits | Content fingerprints on every poll; deletion/recreation recovery | `TestWatcherSameMetadataReplacementAndRecreation` |
|
||||
| Source saving lost comments and widened permissions | Comment preamble, existing modes retained, new files 0600 | `TestSaveCommentsPermissionsAndFailure` |
|
||||
| Atomic types were inconsistently registered/serialized | Exact type matching for duration/time/IP/CIDR/URL and pointer forms | `TestAtomicValuesAndFileRoundTrip` |
|
||||
| A missing file could hide a joined invalid CLI/environment error | Missing-file fallback only when other sources succeed | `TestBuilderDoesNotHideInvalidSourceBehindMissingFile` |
|
||||
| Required registration was a no-op; overlapping/duplicate fields were ambiguous | Required paths validated at Build; staged registration rejects conflicts | `TestRegistrationAndRequiredContracts` |
|
||||
| Default source selection and narrow target schemas could be inconsistent | Default precedence honored; explicit defaults must match the typed target | `TestRegistrationAndRequiredContracts` |
|
||||
|
||||
Reproduction against original main `ccd280b`: fractional-to-integer conversion
|
||||
silently produced 1 from 1.5; modifying an input slice changed its registered
|
||||
default; an out-of-range CLI batch returned success; and requesting a refreshed
|
||||
AsStruct changed an earlier result under its reader. All four were reproduced with
|
||||
public-API probes; committed regressions cover the corrected behavior.
|
||||
|
||||
## Dependency and scope decision
|
||||
|
||||
Mapstructure is replaceable for the package's actual object model. The replacement
|
||||
supports TOML field names, ordinary containers, pointers and the existing standard
|
||||
atomic types. It does not reproduce mapstructure's broad weak coercions or add a
|
||||
custom hook API. Numeric correctness is shared with lixenwraith/toml.
|
||||
|
||||
`go list -deps ./...` reports only the standard library, lixenwraith/toml and this
|
||||
module. BurntSushi TOML, mapstructure and YAML are removed from runtime code.
|
||||
Testify remains test-only, so its transitive YAML dependency still appears in go.mod
|
||||
and go.sum. JSON/YAML files and tags are unsupported, with explicit rejection tests.
|
||||
|
||||
No global reflection cache or lock was introduced. Known container sizes are used
|
||||
for allocation. Stored values are immutable after admission. One watcher worker
|
||||
owns observation/debounce state, and subscription cleanup has no per-subscriber
|
||||
goroutine. File I/O and environment callbacks execute outside Config locks.
|
||||
|
||||
## Verification and limits
|
||||
|
||||
The full unit and race suites and go vet pass with Go 1.27.1. Numeric fuzzing ran
|
||||
for 10 seconds and passed 234,155 executions, covering full uint64 preservation,
|
||||
signed boundaries and narrowing. The 386 and Windows test binaries cross-compile
|
||||
locally. This host cannot execute 386 binaries; CI executes that suite and also
|
||||
runs race tests, vet, fuzzing and Windows compilation. Final checks are on the PR.
|
||||
|
||||
TOML's supported subset is unchanged. Native datetime syntax is not added; time.Time
|
||||
is represented by a quoted RFC3339Nano string. Full uint64 works in memory but values
|
||||
above MaxInt64 cannot be saved as TOML integers. Comment text survives as a preamble;
|
||||
locations and formatting do not. Unknown file keys are not saved. Depth is bounded
|
||||
at 128 for configuration graphs. Live application validators remain an application
|
||||
responsibility; Builder validators run only during initialization. Notifications
|
||||
are best effort, and file timeouts prevent late publication without forcibly
|
||||
interrupting kernel I/O. See the linked topic guides for migration details.
|
||||
Reference in new issue
Block a user