Add bounded sources and strict YAML parsing
This commit is contained in:
79
docs/config.md
Normal file
79
docs/config.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Configuration Input Contract
|
||||
|
||||
This document owns ConfigKit's currently implemented source-input and YAML syntax
|
||||
contracts. The parser and owned document representation are private; a public typed
|
||||
loading lifecycle has not been implemented yet.
|
||||
|
||||
## Sources
|
||||
|
||||
ConfigKit exposes opaque sources through these constructors:
|
||||
|
||||
| Constructor | Current contract |
|
||||
| --- | --- |
|
||||
| `File(path)` | Requires a nonempty path, opens a regular file for each consumption, and closes only the library-owned file handle. Missing, inaccessible, unreadable, directory, and other nonregular inputs fail. |
|
||||
| `Bytes(label, data)` | Requires a nonempty, non-secret diagnostic label and snapshots bytes during construction. Later caller mutation cannot affect the source. |
|
||||
| `Reader(label, input)` | Requires a nonempty, non-secret label and non-nil reader. The reader is claimed once across all copies of the source, consumed but never closed, and cannot be reused. |
|
||||
| `NoSource()` | Represents an explicit absence of input and creates no source record. Its defaults-only lifecycle behavior will become available with `Load`. |
|
||||
|
||||
The zero `Source` is invalid. Constructor argument failures are retained inside the
|
||||
opaque source and become safe structured diagnostics when the source is consumed.
|
||||
File sources can observe file changes between consumptions; byte sources cannot.
|
||||
|
||||
Each source is limited to 8 MiB. A load will be limited to 64 MiB across all source
|
||||
and override input when those layers are implemented. Reads request at most the
|
||||
remaining allowance plus one byte so excess data is rejected rather than silently
|
||||
truncated. Data returned together with a read error is not accepted as partial input.
|
||||
|
||||
## YAML documents
|
||||
|
||||
The private YAML boundary currently accepts exactly one nonempty document whose root
|
||||
is a mapping. Comments and block or flow collections are supported. It rejects:
|
||||
|
||||
- empty input or an empty document;
|
||||
- every additional document, including an empty one;
|
||||
- duplicate decoded mapping keys;
|
||||
- non-string mapping keys;
|
||||
- explicit tags, anchors, aliases, and merge keys;
|
||||
- a quoted or plain mapping key equal to `<<`; and
|
||||
- input exceeding the fixed depth or node limits.
|
||||
|
||||
Mapping key comparison is exact: it performs no case folding or Unicode
|
||||
normalization. The private document tree retains declaration order, exact validated
|
||||
number spelling, source identifiers, and separate key/value line and column
|
||||
locations. It contains no upstream parser nodes or types.
|
||||
|
||||
Root depth is zero. Input depth is limited to 256 and each parsed input tree to
|
||||
1,000,000 nodes, counting mapping keys as input nodes. The upstream parser also has
|
||||
a private calibrated depth guard; passing that guard never bypasses ConfigKit's tree
|
||||
limits.
|
||||
|
||||
## Scalars
|
||||
|
||||
Scalar meaning is determined by ConfigKit rather than upstream coercion:
|
||||
|
||||
| Input form | Meaning |
|
||||
| --- | --- |
|
||||
| Quoted, literal, or folded scalar | String |
|
||||
| Plain `true` or `false` | Boolean |
|
||||
| Plain `null`, `~`, or an empty mapping value | Null |
|
||||
| JSON decimal number | Number, retaining its exact spelling |
|
||||
| Date/time-looking or other ordinary plain text | String |
|
||||
|
||||
JSON numbers permit an optional minus, a zero or nonzero decimal integer without a
|
||||
leading zero, an optional fraction with at least one digit, and an optional decimal
|
||||
exponent. Hexadecimal, octal, digit separators, leading plus, leading/trailing-dot
|
||||
forms, incomplete exponents, and non-finite values are rejected. Legacy boolean
|
||||
words (`yes`, `no`, `on`, and `off`) and non-lowercase variants of the reserved
|
||||
boolean/null words are rejected unless quoted.
|
||||
|
||||
Mapping keys use the same scalar classification and must classify as strings. Quote
|
||||
keys that otherwise classify as a boolean, number, or null.
|
||||
|
||||
## Safe failures
|
||||
|
||||
Source failures use stable `source.*` codes and YAML failures use stable `yaml.*`
|
||||
codes declared by the root package. Diagnostics contain safe classifications,
|
||||
semantic paths when applicable, and available source coordinates. Raw parser,
|
||||
conversion, reader-error, and input text is not forwarded. Source labels and
|
||||
diagnostic messages are application-visible and therefore must never contain
|
||||
secrets; terminal control characters are escaped by `WriteDiagnostics`.
|
||||
Reference in New Issue
Block a user