Revision 0.9 adds section 20, the cadence and event subsystems contract, and carries two corrections the implementation forced. Section 6.1 now states that a duration is the authored literal or a non-negative finite number already in milliseconds, since a DurationSpec may be the resolved output of a ValueSpec or a bounded TimeSpec, with the one documented exception of an automation track's `at`, which 19.1 keeps literal-only so that point ordering stays decidable at import. Section 20.11 documents the rejection of an undeclared input name in an event action's `with` map as ERR_UNKNOWN_FIELD — the section's own convention for that shape of error, replacing an invented code that appeared nowhere in the registry. The review record is committed with the code it describes: the two code triages that found these defects, the reconciliation plan that sequenced the fixes, and a follow-up debt record listing what was deliberately left open — the unchecked JSON Schema artifact, degenerate path arcs, post-effect transient allocation, the window-traffic fixture's per-copy wrap bounds, and the unstated `ownership: "persistent"` value on a sound action. None of the five blocks phase 6; all five are written down rather than dropped. Devlog entries are backfilled for the two milestones that had none: phase 3c slice 2, the audio lifecycle and voice ceilings, and slice 4d, the renderer core. The implementation status summary now reflects the reconciled state rather than the in-flight one. 231 tests pass. tools/verify-spec-contract.py reports 46 declared diagnostic codes with every used code resolving and its two long-standing unresolved cross-references unchanged. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01ShxxFqFmCUDQnQvFNm4TKy
15 KiB
Spec Review — Kimi K3
Source: Kimi K3 Scope: sections 14–16 (with line references) Received: 2026-09-06 Status: raw, untriaged — verbatim as delivered
Defects
1. §15.13/§15.11 vs §14.4 — component exposed parameters are legal modulation/automation targets with no defined effect (Class 6/5)
What it says: The 15.13 registry (line 1085) lists component / <exposed-parameter-id> as a modulation target; 15.11 (line 1045) repeats it; 16.1 (line 1293) makes the same properties automation targets; 15.19 trace 4 (line 1250) requires testing that "an exposed parameter is a legal modulation target." But the only way a component's internals consume a parameter is { "ref": "inputs.<id>" } in a node field (15.15, line 1166), and 14.4 (line 629) resolves every node field exactly once at instantiation, "constant for that node instance's lifetime"; 15.11 (line 1039) likewise resolves the supplied values once.
Why wrong: After instantiation, nothing inside the component ever observes the parameter again, so the 15.13 modulation sum (and any 16.1 automation curve) applied to an exposed parameter has no defined effect on anything audible. The registry declares a legal target whose processing semantics do not exist; an implementer cannot satisfy trace 15.19-4 without inventing behavior, and the two natural readings (fields frozen per 14.4 vs. live inputs.* refs) contradict each other.
Smallest fix: Either remove the component row from the 15.13 registry (and exclude exposed parameters from 16.1 targets and 15.19 trace 4), or add one sentence to 15.15 stating that node fields of the exact form { "ref": "inputs.<id>" } track the parameter's current value as an exception to 14.4's resolve-once rule. The first is smaller.
2. §14.12/§7 — ERR_INVALID_RANGE_ORDER is filed Semantic-only, but the sample-hold rule requires instantiation-time values (Class 3 + 7)
What it says: 14.12 declares min/max as full ValueSpec<number> in 14.4 scope (lines 815–816) — they may be random and resolve once at instantiation. Line 819: "min resolving to a value greater than or equal to max is ERR_INVALID_RANGE_ORDER." Section 7 (line 286) files that code as Semantic only, with the cause "...not in strictly increasing order after resolution."
Why wrong: Semantic validation runs at import with no seed, no streams, no runtime state — 14.5 (line 645) states validation "never opens an AudioContext" and tier 1 checks only values that "resolve to a literal"; 9.3 derives streams from the performance's recorded root seed, which does not exist at import. For a legal document such as "min": { "random": { "min": -5, "max": 5 } }, "max": 2, the order check cannot run at the semantic stage, and the Semantic-only filing forbids the only stage (instantiation) where the resolved values exist. Section 7's own cause text ("after resolution") concedes this. The rule is unenforceable as staged. (The 16.1 use of the same code for automation at ordering is fine — at is a duration literal.)
Smallest fix: Refile ERR_INVALID_RANGE_ORDER in section 7 as Semantic / Runtime (mirroring ERR_OUT_OF_BOUNDS' dual filing), and in 14.12 state that literal bounds are checked at import while procedural bounds are checked when resolved at instantiation.
3. §15.14 vs §16.1 — automation track/point limits are called "runtime ceilings rather than document properties" yet are enforced with a Semantic code (Class 3 staging contradiction)
What it says: 15.14 (line 1132): "The remaining PRD 58 limits — approximate one-shot voices (64), approximate continuous sounds (16), automation tracks (64), and automation points (256) — are runtime ceilings rather than document properties..." But 16.1 (line 1318): exceeding 64 tracks or 256 points "is ERR_NODE_LIMIT_EXCEEDED," which section 7 (line 285) files as Semantic, and 16.11 trace 6 (line 1483) requires 65/257 to fail and 64/256 to pass in the automated, no-audio-device group.
Why wrong: Automation tracks and points are authored in the document's automation arrays and are countable after static expansion (15.19 trace 7 confirms expansion runs with no AudioContext). They are document properties and are semantically enforced; 15.14's sentence misclassifies them, so an implementer following 15.14 would defer them to runtime and fail trace 16.11-6. (The voice ceilings in the same sentence are correctly runtime per 16.6.)
Smallest fix: Delete "automation tracks (64), and automation points (256)" from the 15.14 sentence. Optionally extend section 7's ERR_NODE_LIMIT_EXCEEDED cause parenthetical (line 285), which currently omits the automation-limits use introduced in 16.1.
4. §16.1 — automation point values draw from the seeded stream with no documented sampling boundary or order (Class 4)
What it says: Line 1289 makes each point { "at": <duration literal>, "value": ValueSpec<number> }; line 1297: "A track's values remain full ValueSpecs and may be random." Nothing states when they are sampled or in what stream order. 14.4 (line 629) documents resolve-once sampling only for node-object fields; 15.12 (line 1067) fixes the sampling order only for route depth values; 9.3 (line 457) requires "the containing object's documented instantiation or invocation boundary" and depth-first, property-document order — no documented boundary or order exists for the automation array. (The stream identity itself is inherited from the sound instance; what is missing is the boundary and the consumption order.)
Why wrong: Two conforming implementations may sample track values at different positions in the sound stream (before/after node fields, before/after route depths), producing different values for the same seed — silently breaking the 9.3 reproducibility promise that 14.6 explicitly claims for resolved-once audio values. It is also unstated whether a track's values are sampled once per sound instance at all.
Smallest fix: One sentence in 16.1 fixing boundary and order, e.g.: "A track's point values are resolved once at the owning sound instance's instantiation boundary, sampled from the sound instance's stream in depth-first, property-document order with automation taken after nodes and routes."
5. §15.10/§16.5 and §14.7 — undefined result when every mode or partial is omitted (Class 6 edge case)
What it says: 15.10 (line 1024) and 14.7 (line 690) omit over-ceiling modes/partials at instantiation and state omission "is a routine consequence of legal authoring and raises no diagnostic." 16.5 (line 1387) defines a resonator's contribution as "the longest decay among its retained modes."
Why wrong: A legal document can have all entries omitted (e.g. fundamental: 20000 with modes: [{ "ratio": 2 }] on a 44.1 kHz device, where audioMaxFrequency = 19845). "Longest decay among retained modes" is then a maximum over an empty set — undefined — and it feeds the one-shot ending computation of 16.5. Likewise a custom oscillator with all partials omitted has no defined output.
Smallest fix: State that a resonator with no retained modes contributes zero (and is silent), and that a custom oscillator with all partials omitted produces silence.
6. §15.16 — name/tags length caps state no breach behavior (Class 5)
What it says: Lines 1197–1198: name "at most 128 characters"; tags "at most 16 entries of at most 32 characters." No diagnostic is named. Every other quantitative limit in §§14–16 names its code, and the in-section conventions don't cover string/array lengths (ERR_TYPE_MISMATCH covers bad enum tokens, ERR_OUT_OF_BOUNDS covers numeric ranges; section 7's ERR_SCHEMA_VALIDATION cause covers "malformed top-level shapes," which sounds.<id> is not).
Smallest fix: Name the diagnostic for exceeding these caps (e.g. ERR_SCHEMA_VALIDATION).
7. §16.2 — misattributed cross-reference (borderline Class 8)
Line 1332 cites "the parameter-masking rule of section 8.1" for "releasing an override returns toward the current stored value rather than an obsolete snapshot." Section 8.1 exists but contains no such rule — its only masked-override text (line 318) concerns the UI override indicator. The behavior is specified in 8.3 (line 370, masked stages continue) and 8.4 (line 392, currentLowerValue recomputed every tick).
Smallest fix: cite 8.3/8.4 instead of 8.1.
Classes with no findings
- Class 1 (prose contradicting a JSON example in the same section): none. I checked every example and invalid case in 14.3–14.13, 15.2–15.17, and 16.1 against its section's tables and rules (ranges, enums, defaults, named diagnostics); all match, including the subtle ones (14.7's empty-
harmonicsinvalid case correctly maps toERR_UNKNOWN_FIELD, notERR_SCHEMA_VALIDATION; 15.16'soneshotexample genuinely has a determinable ending under 16.5). - Class 2 (field missing from its container's allowed-field table): none.
automationis in 14.3's graph-object table;parameters/inputin 15.15's;mode/releasein 15.16's recipe table; all node fields, route fields (15.12), track fields (16.1), sound fields (15.16), and bus fields (15.17) are tabulated in their containers. - Class 6, beyond findings 1 and 5: checked and cleared — 16.5's longest-path termination (acyclic route graph + nesting ≤ 8), the delay tail formula's domain over
feedback ∈ [0, 0.95], the exponential-interpolation fallback, the 16.6 eviction order, and lifecycle transition totality (including the second-stop no-op). - Class 7, beyond finding 2: all 24
ERR_/WARN_/INFO_codes used in §§14–16 are present in the section 7 table (verified by mechanical extraction); the 15.18 and 16.10 "new codes" tables match section 7's entries in stage and wording. OnlyERR_INVALID_RANGE_ORDERis mis-staged (finding 2), andERR_NODE_LIMIT_EXCEEDED's cause list omits its 16.1 automation use (folded into finding 3). - Class 8, beyond finding 7: all internal references (1.3, 4, 6.1, 6.2, 7, 8.1, 8.2, 9.3, 11, and all 14.x/15.x/16.x) resolve, and every PRD reference used in §§14–16 (33–62, 117–118, 120, 129) exists as a numbered PRD section.
Second output — Kimi K3 (condensed restatement)
Same seven defects, delivered as a summary pass. Line numbers refer to docs/XZBT_0-1_Format_Specification.md. Verbatim as delivered.
Review of XZBT format spec sections 14–16 complete. Seven defects found, ranked by severity (line numbers refer to docs/XZBT_0-1_Format_Specification.md):
-
§15.13/§15.11 vs §14.4 — component exposed parameters are legal modulation/automation targets with no defined effect (unimplementable). The 15.13 registry (line 1085) and 15.11 (line 1045) make
<component-node-key>.<parameter-id>a modulation target, and 16.1 makes it an automation target. But the only internal consumption path is{ "ref": "inputs.<id>" }in a node field (15.15, line 1166), and 14.4 (line 629) freezes every node field at instantiation "for that node instance's lifetime." Nothing ever re-reads the parameter, so the modulation sum/automation curve has no defined audible effect, and acceptance trace 15.19-4 cannot be satisfied as written. Smallest fix: remove thecomponentrow from the 15.13 registry (and exclude exposed parameters in 16.1 and trace 15.19-4), or state in 15.15 that exact-forminputs.*ref fields track the parameter's current value as an exception to 14.4. -
§14.12/§7 —
ERR_INVALID_RANGE_ORDERis filed Semantic-only but the sample-hold rule needs instantiation-time values.min/maxare full ValueSpecs resolved once at instantiation (14.12 lines 815–816); the order rule (line 819) therefore cannot be checked at import for legal procedural bounds — semantic validation has no seed, streams, or runtime state (14.5 line 645; 9.3). Section 7 (line 286) files the code as Semantic only while its own cause says "after resolution." Smallest fix: refile asSemantic / Runtimein section 7 and state in 14.12 that literal bounds are checked at import, procedural bounds at instantiation. (The 16.1 use of the same code is fine —atis a literal.) -
§15.14 vs §16.1 — staging contradiction on automation limits. 15.14 (line 1132) calls automation tracks (64) and points (256) "runtime ceilings rather than document properties," but 16.1 (line 1318) enforces them with
ERR_NODE_LIMIT_EXCEEDED, a Semantic code (section 7 line 285), and 16.11 trace 6 requires import-stage enforcement. Tracks/points are countable in the document after static expansion; the voice ceilings in the same sentence are correctly runtime. Smallest fix: delete the two automation limits from the 15.14 sentence; optionally extendERR_NODE_LIMIT_EXCEEDED's cause list in section 7 to mention automation. -
§16.1 — automation point values draw from the seeded stream with no documented sampling boundary or order. Points are
{ "at": literal, "value": ValueSpec }and values "may be random" (lines 1289, 1297), but 14.4 documents resolve-once sampling only for node fields and 15.12 only fixes route-depthorder; nothing fixes when or in what stream order track values sample (9.3 requires a documented boundary). Two conforming implementations can consume the stream in different orders and diverge for the same seed, breaking the 9.3/14.6 reproducibility promise. Smallest fix: one sentence in 16.1 fixing the instantiation boundary and the position ofautomationin the depth-first property-document sampling order. -
§15.10/§16.5 and §14.7 — undefined result when every mode/partial is omitted. A legal document can have all resonator modes omitted at instantiation (e.g.
fundamental: 20000,modes: [{ "ratio": 2 }]on a 44.1 kHz device); 16.5's "longestdecayamong its retained modes" is then a max over an empty set, and a custom oscillator with all partials omitted has no defined output. Smallest fix: state both contribute zero / produce silence. -
§15.16 —
name(128 chars) andtags(16 × 32 chars) caps name no diagnostic on breach, unlike every other quantitative limit in §§14–16; no in-section convention covers length caps. Smallest fix: name the code (e.g.ERR_SCHEMA_VALIDATION). -
§16.2 line 1332 — mis-citation: "the parameter-masking rule of section 8.1" is not in 8.1; the behavior lives in 8.3 (line 370) and 8.4 (line 392). Smallest fix: cite 8.3/8.4.
Classes with no findings: Class 1 (all in-section JSON examples match their prose, including invalid-case codes); Class 2 (every introduced field appears in its container's allowed-field table); Class 7 otherwise (all 24 codes used in §§14–16 verified present in the section 7 table; 15.18/16.10 match it); Class 8 otherwise (all internal section references and all cited PRD sections 33–62, 117–118, 120, 129 exist). Nothing in the excluded deliberate-design list was reported. No edits were made to the document.