From 4b063dd51f62afb5679a3cfa9fba57f142be8053 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 19 May 2026 20:18:23 +0100 Subject: [PATCH] Use CultLib for sound claim cache --- patches/aquasynth-patch-cultcache.cc | Bin 0 -> 13156 bytes patches/aquasynth-patch-cultcache.json | 127 ---------- src/AquaSynth.Core/AquaSynth.Core.csproj | 4 + src/AquaSynth.Core/CultCachePatchDocument.cs | 222 ++++++++++++++---- state/evidence.jsonl | 1 + state/map.yaml | 4 +- state/scratch.md | 14 +- .../CultCachePatchDocumentTests.cs | 42 ++-- 8 files changed, 221 insertions(+), 193 deletions(-) create mode 100644 patches/aquasynth-patch-cultcache.cc delete mode 100644 patches/aquasynth-patch-cultcache.json diff --git a/patches/aquasynth-patch-cultcache.cc b/patches/aquasynth-patch-cultcache.cc new file mode 100644 index 0000000000000000000000000000000000000000..2ee4b85a54a3ba39a8b8166bb8e345abf674db5f GIT binary patch literal 13156 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 NmrP5?G?Hv4`hN{0w%Pyy literal 0 HcmV?d00001 diff --git a/patches/aquasynth-patch-cultcache.json b/patches/aquasynth-patch-cultcache.json deleted file mode 100644 index 018bf71..0000000 --- a/patches/aquasynth-patch-cultcache.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "type": "cultcache.document.aquasynth.sound_claims", - "schema": "cultcache/aquasynth/sound-claims.v1", - "version": 1, - "generated_from": [ - "patches/library.yaml", - "src/AquaSynth.Core/ReferenceRebuilds.cs", - "docs/ipa-vocal-tract-roadmap.md", - "state/scratch.md" - ], - "patch_database": { - "source_path": "patches/library.yaml", - "entries": [ - { "path": "patches/808/clap.aqua", "family": "808", "name": "clap", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/808/cowbell.aqua", "family": "808", "name": "cowbell", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/808/hat.aqua", "family": "808", "name": "hat", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/808/kick.aqua", "family": "808", "name": "kick", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/808/snare.aqua", "family": "808", "name": "snare", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/808/tom.aqua", "family": "808", "name": "tom", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/advanced/aurora-pad.aqua", "family": "advanced", "name": "aurora-pad", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/advanced/glass-creature.aqua", "family": "advanced", "name": "glass-creature", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/advanced/machine-breath.aqua", "family": "advanced", "name": "machine-breath", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/advanced/ritual-sequence.aqua", "family": "advanced", "name": "ritual-sequence", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/bfxr/coin-spark.aqua", "family": "bfxr", "name": "coin-spark", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/bfxr/portal-chirp.aqua", "family": "bfxr", "name": "portal-chirp", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/bfxr/shield-pop.aqua", "family": "bfxr", "name": "shield-pop", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/bfxr/ui-bloom.aqua", "family": "bfxr", "name": "ui-bloom", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/dx7/algorithm-32-additive-organ.aqua", "family": "dx7", "name": "Algorithm 32 additive organ", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/dx7/algorithm-8-bright-pair.aqua", "family": "dx7", "name": "Algorithm 8 bright pair", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/dx7/public-domain-mc-mm-5-3.aqua", "family": "dx7", "name": "Public-domain MC-MM 5-3", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/dx7/public-domain/prc-synth1-calibrated.aqua", "family": "dx7/public-domain", "name": "PRC SYNTH1 calibrated", "source": "analog1.syx voice 17 parity probe", "notes": "Generated from latest calibrated DX7 lowering." }, - { "path": "patches/examples/language-tour.aqua", "family": "examples", "name": "Language Tour", "source": "BuiltInScripts.PatchScriptExample", "notes": "Parser and DSL feature tour." }, - { "path": "patches/fm-bell/bell.aqua", "family": "fm-bell", "name": "bell", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/fm-bell/chime.aqua", "family": "fm-bell", "name": "chime", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/fm-bell/coin.aqua", "family": "fm-bell", "name": "coin", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/fm-bell/gong.aqua", "family": "fm-bell", "name": "gong", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/blip.aqua", "family": "sfxr", "name": "blip", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/classic/classic-sfxr-abstract-golf.aqua", "family": "sfxr/classic", "name": "Classic SFXR Abstract Golf", "source": "BuiltInScripts.ClassicSfxrAbstractGolfScript", "notes": "Compressed SFXR-derived multi-sound golf fixture." }, - { "path": "patches/sfxr/explosion.aqua", "family": "sfxr", "name": "explosion", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/hit.aqua", "family": "sfxr", "name": "hit", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/jump.aqua", "family": "sfxr", "name": "jump", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/laser.aqua", "family": "sfxr", "name": "laser", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/pickup.aqua", "family": "sfxr", "name": "pickup", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/sfxr/powerup.aqua", "family": "sfxr", "name": "powerup", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/wobble-bass/growl.aqua", "family": "wobble-bass", "name": "growl", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/wobble-bass/neuro.aqua", "family": "wobble-bass", "name": "neuro", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/wobble-bass/talker.aqua", "family": "wobble-bass", "name": "talker", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." }, - { "path": "patches/wobble-bass/yoy.aqua", "family": "wobble-bass", "name": "yoy", "source": "BuiltInScripts.ReferenceScripts", "notes": "Stock reference patch exported from the in-code catalog." } - ] - }, - "patch_claims": [ - { - "id": "zyn/project-additive-lead/aquasynth", - "patch_path": null, - "reference": { "synth_or_source": "ZynAddSubFX project-authored fixture", "fixture_or_artifact": "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/additive-lead.xiz", "license_scope": "project-authored development fixture" }, - "intent": { "perceptual_claim": "A layered additive lead expressed as named harmonic banks rather than anonymous partial piles.", "use_context": "Zyn ADDsynth pressure for AquaSynth harmonic-bank syntax." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "ReferenceRebuildCatalog.ZynRebuilds", "latest_listening_receipt": "missing: no accepted listening receipt recorded for this fixture", "metric_summary": "structural pressure only", "known_lies": ["not exact Zyn ADDsynth oscillator phase/bandwidth semantics", "not exact Zyn free-envelope timing"] } - }, - { - "id": "zyn/project-pad-texture/aquasynth", - "patch_path": null, - "reference": { "synth_or_source": "ZynAddSubFX project-authored fixture", "fixture_or_artifact": "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/pad-texture.xiz", "license_scope": "project-authored development fixture" }, - "intent": { "perceptual_claim": "A slow layered PAD texture with body, shimmer, air, and explicit spectral-cloud source authority.", "use_context": "PAD syntax and FFT wavetable pressure." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "artifacts/parity/zyn-pad-reference// when optional Zyn oracle is installed", "latest_listening_receipt": "ear rejected early angry-bees candidate; no final accepted receipt recorded for project-authored pad-texture", "metric_summary": "optional Zyn PAD render comparison writes log-mel/envelope report", "known_lies": ["not full Zyn PAD profile/randomness/pitch-zone behavior", "not arbitrary Zyn free-envelope curves"] } - }, - { - "id": "zyn/project-vocal-layer/aquasynth", - "patch_path": null, - "reference": { "synth_or_source": "ZynAddSubFX project-authored fixture", "fixture_or_artifact": "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/vocal-layer.xiz", "license_scope": "project-authored development fixture" }, - "intent": { "perceptual_claim": "A layered vocal-ish synth where air, body, and breath remain inspectable sound objects.", "use_context": "Formant/layer pressure before the full speech lane." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "ReferenceRebuildCatalog.ZynRebuilds", "latest_listening_receipt": "missing: no accepted listening receipt recorded for this fixture", "metric_summary": "structural pressure only", "known_lies": ["no exact Zyn kit-item/effect routing", "formant motion remains approximate"] } - }, - { - "id": "dx7/algo32-additive-organ/aquasynth", - "patch_path": "patches/dx7/algorithm-32-additive-organ.aqua", - "reference": { "synth_or_source": "DX7 algorithm topology", "fixture_or_artifact": "in-code topology reference", "license_scope": "derived structural reference" }, - "intent": { "perceptual_claim": "DX7 algorithm 32 as the easy six-carrier additive case.", "use_context": "Operator topology pressure where AquaSynth should avoid inventing FM machinery it does not need." }, - "tier": "sketch", - "proof": { "latest_render_artifact": "parser/export tests", "latest_listening_receipt": "missing: topology sketch has no listening receipt", "metric_summary": "structural tests only", "known_lies": ["not exact DX7 envelope execution", "not ROM output compensation"] } - }, - { - "id": "dx7/algo8-bright-pair/aquasynth", - "patch_path": "patches/dx7/algorithm-8-bright-pair.aqua", - "reference": { "synth_or_source": "DX7 algorithm topology", "fixture_or_artifact": "in-code topology reference", "license_scope": "derived structural reference" }, - "intent": { "perceptual_claim": "DX7 algorithm 8 as an explicit AquaSynth operator graph with visible modulation routes.", "use_context": "Operator graph pressure for summed stacks and feedback." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "parser/export tests", "latest_listening_receipt": "missing: topology pressure patch has no listening receipt", "metric_summary": "structural tests only", "known_lies": ["not calibrated DX7 feedback register", "not exact DX7 EG"] } - }, - { - "id": "dx7/public-domain-mc-mm-5-3/aquasynth", - "patch_path": "patches/dx7/public-domain-mc-mm-5-3.aqua", - "reference": { "synth_or_source": "Dexed/dexed-py render of public-domain DX7 SysEx", "fixture_or_artifact": "tests/AquaSynth.Dsl.Tests/Fixtures/Dx7/PublicDomain/analog1.syx#13", "license_scope": "public-domain development fixture; not packaged" }, - "intent": { "perceptual_claim": "A short C3-derived sine-like DX7 voice rebuilt as an AquaSynth parity rung.", "use_context": "Lawful rendered-audio parity proof for the DX7 lane." }, - "tier": "parity", - "proof": { "latest_render_artifact": "Dx7ReferenceParityTests optional dexed-py/Faust render report", "latest_listening_receipt": "metric-gated parity; no explicit human listening receipt recorded", "metric_summary": "score>=0.75 log_mel<0.12 envelope<0.10", "known_lies": ["matches rendered behavior, not exact operator-level execution", "uses AquaSynth ADSR timing matched to audio"] } - }, - { - "id": "dx7/public-domain-prc-synth1-calibrated/aquasynth", - "patch_path": "patches/dx7/public-domain/prc-synth1-calibrated.aqua", - "reference": { "synth_or_source": "Dexed/dexed-py render of public-domain DX7 SysEx", "fixture_or_artifact": "tests/AquaSynth.Dsl.Tests/Fixtures/Dx7/PublicDomain/analog1.syx#17", "license_scope": "public-domain development fixture; not packaged" }, - "intent": { "perceptual_claim": "A hard DX7 stacked-FM calibration probe that should keep body, attack, and harmonic grit believable.", "use_context": "DX7 calibration pressure for route scaling, feedback, detune, operator levels, and envelope shape." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "artifacts/parity/dx7-prc-synth1// when optional dexed-py and Faust are installed", "latest_listening_receipt": "several user listening corrections recorded in state/scratch.md; not promoted to accepted parity", "metric_summary": "latest recorded calibrated probe: log-mel around 0.17-0.24 depending rung; pressure target, not accepted parity", "known_lies": ["DX7 EG remains approximated", "hard target still calibration pressure"] } - } - ], - "speech_claims": [ - { - "id": "speech/espeak-ng-tiny-workout", - "utterance_source": { "text_or_ipa": "a, pa, ta, ka, sa, ma", "phoneme_source": "tests/AquaSynth.Dsl.Tests/EspeakNgGradientDescentTests.cs", "reference_renderer": "eSpeak NG when ESPEAK_NG or espeak/espeak-ng is installed" }, - "target": { "anatomy_or_profile": "neutral human-ish tract controller profile", "phonetic_constraints": ["bilabial stop pressure", "alveolar stop pressure", "velar stop pressure", "sibilant turbulence", "nasal velum opening", "open vowel baseline"] }, - "intent": { "perceptual_claim": "AquaSynth should learn a tiny speech-control mapping against generated reference speech instead of hand-filled target paperwork.", "use_context": "First curriculum rung for Weksa IPA/phonetic utterance rendering." }, - "tier": "pressure", - "proof": { "latest_render_artifact": "artifacts/parity/espeak-ng-gradient-descent/-tiny/training-report.md when eSpeak NG is installed", "latest_listening_receipt": "missing: no human accepted speech artifact yet", "metric_summary": "optional fixture asserts chained learning loss reduction and records log-mel means", "known_lies": ["not intelligible AquaSynth speech yet", "reference supervision still eSpeak-shaped"] } - }, - { - "id": "speech/compiled-faust-loss-surface", - "utterance_source": { "text_or_ipa": "controller-output vector from learned phonetic pipeline", "phoneme_source": "SpeechBackpropagationPipeline + VocalTractNeuralMapper", "reference_renderer": "compiled native Faust speech-loss probe" }, - "target": { "anatomy_or_profile": "current minimal controllable speech synth; future curriculum target slot", "phonetic_constraints": ["all neural mapper outputs exported as speech/output/N controls", "cutoff clamped below Nyquist", "candidate batches render without recompiling DSP"] }, - "intent": { "perceptual_claim": "The optimizer can blast many controller attempts through one compiled Faust surface and climb toward a reference match.", "use_context": "Curriculum learning loss surface before richer anatomy and parity targets." }, - "tier": "proof", - "proof": { "latest_render_artifact": "CompiledFaustRenderedSpeechLossSurfaceReusesOnePatchWithExportedOutputKnobsWhenToolchainIsAvailable", "latest_listening_receipt": "missing: optimizer plumbing proof only", "metric_summary": "opt-in native batch proof renders multiple candidates through one compiled patch and checks lower loss for closer controls", "known_lies": ["finite-difference controller gradient, not analytic Faust DSP gradient", "minimal synth rung, not full vocal tract"] } - } - ] -} diff --git a/src/AquaSynth.Core/AquaSynth.Core.csproj b/src/AquaSynth.Core/AquaSynth.Core.csproj index 71fa159..2c1b24c 100644 --- a/src/AquaSynth.Core/AquaSynth.Core.csproj +++ b/src/AquaSynth.Core/AquaSynth.Core.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/src/AquaSynth.Core/CultCachePatchDocument.cs b/src/AquaSynth.Core/CultCachePatchDocument.cs index 5abf04c..d0db719 100644 --- a/src/AquaSynth.Core/CultCachePatchDocument.cs +++ b/src/AquaSynth.Core/CultCachePatchDocument.cs @@ -1,63 +1,203 @@ -using System.Text.Json.Serialization; +using GameCult.Caching; +using GameCult.Caching.MessagePack; +using MessagePack; namespace AquaSynth.Dsl; +[CultDocument("aquasynth.sound_claims", "aquasynth.sound_claims.v1")] +[CultGlobal] +[MessagePackObject] public sealed record CultCachePatchDocument( - [property: JsonPropertyName("type")] string Type, - [property: JsonPropertyName("schema")] string Schema, - [property: JsonPropertyName("version")] int Version, - [property: JsonPropertyName("generated_from")] IReadOnlyList GeneratedFrom, - [property: JsonPropertyName("patch_database")] CultCachePatchDatabase PatchDatabase, - [property: JsonPropertyName("patch_claims")] IReadOnlyList PatchClaims, - [property: JsonPropertyName("speech_claims")] IReadOnlyList SpeechClaims); + [property: Key(0)] string Type, + [property: Key(1)] string Schema, + [property: Key(2)] int Version, + [property: Key(3)] string[] GeneratedFrom, + [property: Key(4)] CultCachePatchDatabase PatchDatabase, + [property: Key(5)] CultCachePatchClaimCard[] PatchClaims, + [property: Key(6)] CultCacheSpeechClaimCard[] SpeechClaims); +[MessagePackObject] public sealed record CultCachePatchDatabase( - [property: JsonPropertyName("source_path")] string SourcePath, - [property: JsonPropertyName("entries")] IReadOnlyList Entries); + [property: Key(0)] string SourcePath, + [property: Key(1)] CultCachePatchDatabaseEntry[] Entries); +[MessagePackObject] public sealed record CultCachePatchDatabaseEntry( - [property: JsonPropertyName("path")] string Path, - [property: JsonPropertyName("family")] string Family, - [property: JsonPropertyName("name")] string Name, - [property: JsonPropertyName("source")] string Source, - [property: JsonPropertyName("notes")] string Notes); + [property: Key(0)] string Path, + [property: Key(1)] string Family, + [property: Key(2)] string Name, + [property: Key(3)] string Source, + [property: Key(4)] string Notes); +[MessagePackObject] public sealed record CultCachePatchClaimCard( - [property: JsonPropertyName("id")] string Id, - [property: JsonPropertyName("patch_path")] string? PatchPath, - [property: JsonPropertyName("reference")] CultCacheReferenceTruth Reference, - [property: JsonPropertyName("intent")] CultCacheIntentTruth Intent, - [property: JsonPropertyName("tier")] string Tier, - [property: JsonPropertyName("proof")] CultCacheProofTruth Proof); + [property: Key(0)] string Id, + [property: Key(1)] string? PatchPath, + [property: Key(2)] CultCacheReferenceTruth Reference, + [property: Key(3)] CultCacheIntentTruth Intent, + [property: Key(4)] string Tier, + [property: Key(5)] CultCacheProofTruth Proof); +[MessagePackObject] public sealed record CultCacheSpeechClaimCard( - [property: JsonPropertyName("id")] string Id, - [property: JsonPropertyName("utterance_source")] CultCacheUtteranceSourceTruth UtteranceSource, - [property: JsonPropertyName("target")] CultCacheSpeechTargetTruth Target, - [property: JsonPropertyName("intent")] CultCacheIntentTruth Intent, - [property: JsonPropertyName("tier")] string Tier, - [property: JsonPropertyName("proof")] CultCacheProofTruth Proof); + [property: Key(0)] string Id, + [property: Key(1)] CultCacheUtteranceSourceTruth UtteranceSource, + [property: Key(2)] CultCacheSpeechTargetTruth Target, + [property: Key(3)] CultCacheIntentTruth Intent, + [property: Key(4)] string Tier, + [property: Key(5)] CultCacheProofTruth Proof); +[MessagePackObject] public sealed record CultCacheReferenceTruth( - [property: JsonPropertyName("synth_or_source")] string SynthOrSource, - [property: JsonPropertyName("fixture_or_artifact")] string FixtureOrArtifact, - [property: JsonPropertyName("license_scope")] string LicenseScope); + [property: Key(0)] string SynthOrSource, + [property: Key(1)] string FixtureOrArtifact, + [property: Key(2)] string LicenseScope); +[MessagePackObject] public sealed record CultCacheUtteranceSourceTruth( - [property: JsonPropertyName("text_or_ipa")] string TextOrIpa, - [property: JsonPropertyName("phoneme_source")] string PhonemeSource, - [property: JsonPropertyName("reference_renderer")] string ReferenceRenderer); + [property: Key(0)] string TextOrIpa, + [property: Key(1)] string PhonemeSource, + [property: Key(2)] string ReferenceRenderer); +[MessagePackObject] public sealed record CultCacheSpeechTargetTruth( - [property: JsonPropertyName("anatomy_or_profile")] string AnatomyOrProfile, - [property: JsonPropertyName("phonetic_constraints")] IReadOnlyList PhoneticConstraints); + [property: Key(0)] string AnatomyOrProfile, + [property: Key(1)] string[] PhoneticConstraints); +[MessagePackObject] public sealed record CultCacheIntentTruth( - [property: JsonPropertyName("perceptual_claim")] string PerceptualClaim, - [property: JsonPropertyName("use_context")] string UseContext); + [property: Key(0)] string PerceptualClaim, + [property: Key(1)] string UseContext); +[MessagePackObject] public sealed record CultCacheProofTruth( - [property: JsonPropertyName("latest_render_artifact")] string LatestRenderArtifact, - [property: JsonPropertyName("latest_listening_receipt")] string LatestListeningReceipt, - [property: JsonPropertyName("metric_summary")] string MetricSummary, - [property: JsonPropertyName("known_lies")] IReadOnlyList KnownLies); + [property: Key(0)] string LatestRenderArtifact, + [property: Key(1)] string LatestListeningReceipt, + [property: Key(2)] string MetricSummary, + [property: Key(3)] string[] KnownLies); + +public static class CultCachePatchDocumentStore +{ + public static async Task WriteDefaultAsync(string filePath) + { + using var cache = CultCacheMessagePack.Create(filePath, new CultCacheOpenOptions + { + PullOnOpen = false + }); + await cache.UpsertAsync( + CultCachePatchDocumentCatalog.CreateDefault(), + new CultRecordHandle(new CultRecordKey(CultCachePatchDocumentCatalog.Key))) + .ConfigureAwait(false); + await cache.FlushAsync().ConfigureAwait(false); + } + + public static async Task ReadAsync(string filePath) + { + using var cache = await CultCacheMessagePack.OpenAsync(filePath).ConfigureAwait(false); + if (!cache.TryGet(new CultRecordKey(CultCachePatchDocumentCatalog.Key), out CultCachePatchDocument? document)) + { + throw new InvalidOperationException($"CultCache document '{CultCachePatchDocumentCatalog.Key}' was not found in {filePath}."); + } + + return document ?? throw new InvalidOperationException($"CultCache document '{CultCachePatchDocumentCatalog.Key}' resolved as null."); + } +} + +public static class CultCachePatchDocumentCatalog +{ + public const string Type = "cultcache.document.aquasynth.sound_claims"; + public const string Schema = "cultcache/aquasynth/sound-claims.v1"; + public const string Key = "aquasynth:sound-claims"; + + public static CultCachePatchDocument CreateDefault() => + new( + Type, + Schema, + 1, + [ + "patches/library.yaml", + "src/AquaSynth.Core/ReferenceRebuilds.cs", + "docs/ipa-vocal-tract-roadmap.md", + "state/scratch.md" + ], + new CultCachePatchDatabase("patches/library.yaml", [.. PatchEntries]), + [.. PatchClaims], + [.. SpeechClaims]); + + public static readonly IReadOnlyList PatchEntries = + [ + new("patches/808/clap.aqua", "808", "clap", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/808/cowbell.aqua", "808", "cowbell", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/808/hat.aqua", "808", "hat", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/808/kick.aqua", "808", "kick", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/808/snare.aqua", "808", "snare", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/808/tom.aqua", "808", "tom", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/advanced/aurora-pad.aqua", "advanced", "aurora-pad", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/advanced/glass-creature.aqua", "advanced", "glass-creature", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/advanced/machine-breath.aqua", "advanced", "machine-breath", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/advanced/ritual-sequence.aqua", "advanced", "ritual-sequence", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/bfxr/coin-spark.aqua", "bfxr", "coin-spark", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/bfxr/portal-chirp.aqua", "bfxr", "portal-chirp", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/bfxr/shield-pop.aqua", "bfxr", "shield-pop", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/bfxr/ui-bloom.aqua", "bfxr", "ui-bloom", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/dx7/algorithm-32-additive-organ.aqua", "dx7", "Algorithm 32 additive organ", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/dx7/algorithm-8-bright-pair.aqua", "dx7", "Algorithm 8 bright pair", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/dx7/public-domain-mc-mm-5-3.aqua", "dx7", "Public-domain MC-MM 5-3", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/dx7/public-domain/prc-synth1-calibrated.aqua", "dx7/public-domain", "PRC SYNTH1 calibrated", "analog1.syx voice 17 parity probe", "Generated from latest calibrated DX7 lowering."), + new("patches/examples/language-tour.aqua", "examples", "Language Tour", "BuiltInScripts.PatchScriptExample", "Parser and DSL feature tour."), + new("patches/fm-bell/bell.aqua", "fm-bell", "bell", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/fm-bell/chime.aqua", "fm-bell", "chime", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/fm-bell/coin.aqua", "fm-bell", "coin", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/fm-bell/gong.aqua", "fm-bell", "gong", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/blip.aqua", "sfxr", "blip", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/classic/classic-sfxr-abstract-golf.aqua", "sfxr/classic", "Classic SFXR Abstract Golf", "BuiltInScripts.ClassicSfxrAbstractGolfScript", "Compressed SFXR-derived multi-sound golf fixture."), + new("patches/sfxr/explosion.aqua", "sfxr", "explosion", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/hit.aqua", "sfxr", "hit", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/jump.aqua", "sfxr", "jump", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/laser.aqua", "sfxr", "laser", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/pickup.aqua", "sfxr", "pickup", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/sfxr/powerup.aqua", "sfxr", "powerup", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/wobble-bass/growl.aqua", "wobble-bass", "growl", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/wobble-bass/neuro.aqua", "wobble-bass", "neuro", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/wobble-bass/talker.aqua", "wobble-bass", "talker", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog."), + new("patches/wobble-bass/yoy.aqua", "wobble-bass", "yoy", "BuiltInScripts.ReferenceScripts", "Stock reference patch exported from the in-code catalog.") + ]; + + public static readonly IReadOnlyList PatchClaims = + [ + PatchClaim("zyn/project-additive-lead/aquasynth", null, "ZynAddSubFX project-authored fixture", "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/additive-lead.xiz", "project-authored development fixture", "A layered additive lead expressed as named harmonic banks rather than anonymous partial piles.", "Zyn ADDsynth pressure for AquaSynth harmonic-bank syntax.", "pressure", "ReferenceRebuildCatalog.ZynRebuilds", "missing: no accepted listening receipt recorded for this fixture", "structural pressure only", ["not exact Zyn ADDsynth oscillator phase/bandwidth semantics", "not exact Zyn free-envelope timing"]), + PatchClaim("zyn/project-pad-texture/aquasynth", null, "ZynAddSubFX project-authored fixture", "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/pad-texture.xiz", "project-authored development fixture", "A slow layered PAD texture with body, shimmer, air, and explicit spectral-cloud source authority.", "PAD syntax and FFT wavetable pressure.", "pressure", "artifacts/parity/zyn-pad-reference// when optional Zyn oracle is installed", "ear rejected early angry-bees candidate; no final accepted receipt recorded for project-authored pad-texture", "optional Zyn PAD render comparison writes log-mel/envelope report", ["not full Zyn PAD profile/randomness/pitch-zone behavior", "not arbitrary Zyn free-envelope curves"]), + PatchClaim("zyn/project-vocal-layer/aquasynth", null, "ZynAddSubFX project-authored fixture", "tests/AquaSynth.Dsl.Tests/Fixtures/ZynAddSubFX/ProjectAuthored/vocal-layer.xiz", "project-authored development fixture", "A layered vocal-ish synth where air, body, and breath remain inspectable sound objects.", "Formant/layer pressure before the full speech lane.", "pressure", "ReferenceRebuildCatalog.ZynRebuilds", "missing: no accepted listening receipt recorded for this fixture", "structural pressure only", ["no exact Zyn kit-item/effect routing", "formant motion remains approximate"]), + PatchClaim("dx7/algo32-additive-organ/aquasynth", "patches/dx7/algorithm-32-additive-organ.aqua", "DX7 algorithm topology", "in-code topology reference", "derived structural reference", "DX7 algorithm 32 as the easy six-carrier additive case.", "Operator topology pressure where AquaSynth should avoid inventing FM machinery it does not need.", "sketch", "parser/export tests", "missing: topology sketch has no listening receipt", "structural tests only", ["not exact DX7 envelope execution", "not ROM output compensation"]), + PatchClaim("dx7/algo8-bright-pair/aquasynth", "patches/dx7/algorithm-8-bright-pair.aqua", "DX7 algorithm topology", "in-code topology reference", "derived structural reference", "DX7 algorithm 8 as an explicit AquaSynth operator graph with visible modulation routes.", "Operator graph pressure for summed stacks and feedback.", "pressure", "parser/export tests", "missing: topology pressure patch has no listening receipt", "structural tests only", ["not calibrated DX7 feedback register", "not exact DX7 EG"]), + PatchClaim("dx7/public-domain-mc-mm-5-3/aquasynth", "patches/dx7/public-domain-mc-mm-5-3.aqua", "Dexed/dexed-py render of public-domain DX7 SysEx", "tests/AquaSynth.Dsl.Tests/Fixtures/Dx7/PublicDomain/analog1.syx#13", "public-domain development fixture; not packaged", "A short C3-derived sine-like DX7 voice rebuilt as an AquaSynth parity rung.", "Lawful rendered-audio parity proof for the DX7 lane.", "parity", "Dx7ReferenceParityTests optional dexed-py/Faust render report", "metric-gated parity; no explicit human listening receipt recorded", "score>=0.75 log_mel<0.12 envelope<0.10", ["matches rendered behavior, not exact operator-level execution", "uses AquaSynth ADSR timing matched to audio"]), + PatchClaim("dx7/public-domain-prc-synth1-calibrated/aquasynth", "patches/dx7/public-domain/prc-synth1-calibrated.aqua", "Dexed/dexed-py render of public-domain DX7 SysEx", "tests/AquaSynth.Dsl.Tests/Fixtures/Dx7/PublicDomain/analog1.syx#17", "public-domain development fixture; not packaged", "A hard DX7 stacked-FM calibration probe that should keep body, attack, and harmonic grit believable.", "DX7 calibration pressure for route scaling, feedback, detune, operator levels, and envelope shape.", "pressure", "artifacts/parity/dx7-prc-synth1// when optional dexed-py and Faust are installed", "several user listening corrections recorded in state/scratch.md; not promoted to accepted parity", "latest recorded calibrated probe: log-mel around 0.17-0.24 depending rung; pressure target, not accepted parity", ["DX7 EG remains approximated", "hard target still calibration pressure"]) + ]; + + public static readonly IReadOnlyList SpeechClaims = + [ + new("speech/espeak-ng-tiny-workout", new("a, pa, ta, ka, sa, ma", "tests/AquaSynth.Dsl.Tests/EspeakNgGradientDescentTests.cs", "eSpeak NG when ESPEAK_NG or espeak/espeak-ng is installed"), new("neutral human-ish tract controller profile", ["bilabial stop pressure", "alveolar stop pressure", "velar stop pressure", "sibilant turbulence", "nasal velum opening", "open vowel baseline"]), new("AquaSynth should learn a tiny speech-control mapping against generated reference speech instead of hand-filled target paperwork.", "First curriculum rung for Weksa IPA/phonetic utterance rendering."), "pressure", new("artifacts/parity/espeak-ng-gradient-descent/-tiny/training-report.md when eSpeak NG is installed", "missing: no human accepted speech artifact yet", "optional fixture asserts chained learning loss reduction and records log-mel means", ["not intelligible AquaSynth speech yet", "reference supervision still eSpeak-shaped"])), + new("speech/compiled-faust-loss-surface", new("controller-output vector from learned phonetic pipeline", "SpeechBackpropagationPipeline + VocalTractNeuralMapper", "compiled native Faust speech-loss probe"), new("current minimal controllable speech synth; future curriculum target slot", ["all neural mapper outputs exported as speech/output/N controls", "cutoff clamped below Nyquist", "candidate batches render without recompiling DSP"]), new("The optimizer can blast many controller attempts through one compiled Faust surface and climb toward a reference match.", "Curriculum learning loss surface before richer anatomy and parity targets."), "proof", new("CompiledFaustRenderedSpeechLossSurfaceReusesOnePatchWithExportedOutputKnobsWhenToolchainIsAvailable", "missing: optimizer plumbing proof only", "opt-in native batch proof renders multiple candidates through one compiled patch and checks lower loss for closer controls", ["finite-difference controller gradient, not analytic Faust DSP gradient", "minimal synth rung, not full vocal tract"])) + ]; + + private static CultCachePatchClaimCard PatchClaim( + string id, + string? patchPath, + string synthOrSource, + string fixtureOrArtifact, + string licenseScope, + string perceptualClaim, + string useContext, + string tier, + string latestRenderArtifact, + string latestListeningReceipt, + string metricSummary, + IReadOnlyList knownLies) => + new( + id, + patchPath, + new CultCacheReferenceTruth(synthOrSource, fixtureOrArtifact, licenseScope), + new CultCacheIntentTruth(perceptualClaim, useContext), + tier, + new CultCacheProofTruth(latestRenderArtifact, latestListeningReceipt, metricSummary, [.. knownLies])); +} diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 8c693cf..97c6602 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -117,3 +117,4 @@ {"date":"2026-05-19","topic":"faust-rendered-speech-loss","lesson":"For speech learning, Core should accept external synth-output gradients while Faust owns rendered loss evaluation. Finite-difference gradients over controller outputs are honest black-box renderer pressure, but too slow for default tests until render compilation is cached or proxied.","evidence":"Added SpeechBackpropagationPipeline.TrainSingleFromSynthOutputGradient and FaustRenderedSpeechLossSurface. The opt-in AQUASYNTH_RUN_FAUST_SPEECH_LOSS=1 proof renders reference and candidate speech targets through Faust, compares log-mel evidence, and returns a finite-difference output gradient for backpropagation through the learned chain."} {"date":"2026-05-19","topic":"compiled-faust-speech-loss-surface","lesson":"The usable speech loss surface should compile topology once and vary every neural mapper output through exported Faust controls. Batch rendering through a native compiled factory makes finite-difference and curriculum learning plausible; recompiling per candidate is only a proof scaffold.","evidence":"Added native Faust UI control discovery/set support, AquaSynthCompiledPatch.Render(controlValues), and CompiledFaustRenderedSpeechLossSurface with speech/output/N knobs for all mapper outputs. The opt-in proof renders multiple candidates through one compiled patch and caught the need to clamp dynamic filter cutoff below Nyquist."} {"date":"2026-05-19","topic":"cultcache-sound-claim-cards","lesson":"Serious AquaSynth sound claims should be distributed as typed data beside the patch database. Patch and speech claim cards must name the reference/source, intent, tier, proof artifact, latest listening receipt surface, metrics, and known lies; stock sketches stay in the database but should not masquerade as parity without receipts.","evidence":"Added CultCachePatchDocument types, patches/aquasynth-patch-cultcache.json, and tests that load the typed document, check patch database count against library.yaml, and require every ReferenceRebuildCatalog entry to have a claim card."} +{"date":"2026-05-19","topic":"cultcache-cc-artifact-boundary","lesson":"AquaSynth must not impersonate CultCache persistence. The sound-claim fixture should be a real .cc CultCache store produced and consumed through CultLib; AquaSynth owns typed sound-claim meaning, while CultLib owns serialization, schema cataloging, record keys, and MessagePack backing-store mechanics.","evidence":"Deleted the local CultCacheBinaryCodec, replaced the JSON cache artifact with patches/aquasynth-patch-cultcache.cc, added a GameCult.Caching.MessagePack project reference, and updated CultCachePatchDocumentTests to load the fixture through CultCachePatchDocumentStore.ReadAsync."} diff --git a/state/map.yaml b/state/map.yaml index 20a506f..9dfab11 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -40,7 +40,7 @@ modules: faust_compiler: src/AquaSynth.Faust/FaustCompiler.cs native_faust_runtime: src/AquaSynth.Faust/NativeFaustRuntime.cs faust_rendered_speech_loss: src/AquaSynth.Faust/FaustRenderedSpeechLossSurface.cs - cultcache_sound_claim_document: patches/aquasynth-patch-cultcache.json + cultcache_sound_claim_document: patches/aquasynth-patch-cultcache.cc cultcache_sound_claim_types: src/AquaSynth.Core/CultCachePatchDocument.cs dx7_reference_render_tests: tests/AquaSynth.Dsl.Tests/Dx7ReferenceParityTests.cs espeak_ng_reference_tests: tests/AquaSynth.Dsl.Tests/EspeakNgReferenceTests.cs @@ -83,7 +83,7 @@ boundaries: - optional eSpeak NG generated ground-truth fixture for supervised utterance-embedding and synth-driver gradient descent - Faust-rendered speech loss surface in AquaSynth.Faust, using rendered audio analysis and finite-difference controller-output gradients - compiled native Faust speech-loss surface with exported /speech/output/N controls for batch candidate rendering without recompiling DSP - - typed CultCache sound-claim document that bundles the patch database with fixture-backed patch claim cards and speech-lane claim cards + - typed CultCache sound-claim document distributed as a real .cc MessagePack-backed CultCache store via CultLib, bundling the patch database with fixture-backed patch claim cards and speech-lane claim cards dev_only: - public-domain DX7 SysEx fixtures - pinned GPL ZynAddSubFX source for parity tests diff --git a/state/scratch.md b/state/scratch.md index 98f40dd..18c77ca 100644 --- a/state/scratch.md +++ b/state/scratch.md @@ -3,10 +3,14 @@ Current slice: - Added a typed CultCache sound-claim document for CultMesh distribution: - `patches/aquasynth-patch-cultcache.json`. -- Added `CultCachePatchDocument` record types in Core. The document bundles - the full `patches/library.yaml` patch database with patch claim cards and - speech claim cards. + `patches/aquasynth-patch-cultcache.cc`. +- Cut the JSON artifact and the local hand-written MessagePack codec. AquaSynth + owns the typed `CultCachePatchDocument` catalog; CultLib owns cache + serialization through `GameCult.Caching.MessagePack`. +- Added `CultCachePatchDocument` record types in Core. The document bundles the + full `patches/library.yaml` patch database with patch claim cards and speech + claim cards, and `CultCachePatchDocumentStore` reads/writes it through real + CultCache APIs. - Patch claim cards now cover every `ReferenceRebuildCatalog.All()` fixture patch: the three project-authored Zyn rebuilds and the three DX7 reference rebuilds. The PRC SYNTH1 calibrated patch also has a claim card because it is @@ -21,7 +25,7 @@ Current slice: surfaces. - Verification: `dotnet test tests\AquaSynth.Dsl.Tests\AquaSynth.Dsl.Tests.csproj --filter "CultCachePatchDocumentTests" -v minimal`: - 3 passed. + 4 passed. Previous slice: diff --git a/tests/AquaSynth.Dsl.Tests/CultCachePatchDocumentTests.cs b/tests/AquaSynth.Dsl.Tests/CultCachePatchDocumentTests.cs index 4bbf6e0..2455ea4 100644 --- a/tests/AquaSynth.Dsl.Tests/CultCachePatchDocumentTests.cs +++ b/tests/AquaSynth.Dsl.Tests/CultCachePatchDocumentTests.cs @@ -1,4 +1,3 @@ -using System.Text.Json; using AquaSynth.Dsl; namespace AquaSynth.Dsl.Tests; @@ -6,19 +5,16 @@ namespace AquaSynth.Dsl.Tests; public sealed class CultCachePatchDocumentTests { [Fact] - public void CultCachePatchDocumentLoadsAsTypedSoundClaimBundle() + public async Task CultCachePatchDocumentLoadsAsTypedSoundClaimBundle() { var root = RepositoryRoot(); - var documentPath = Path.Combine(root, "patches", "aquasynth-patch-cultcache.json"); - var document = JsonSerializer.Deserialize( - File.ReadAllText(documentPath), - new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + var documentPath = Path.Combine(root, "patches", "aquasynth-patch-cultcache.cc"); + var document = await CultCachePatchDocumentStore.ReadAsync(documentPath); - Assert.NotNull(document); - Assert.Equal("cultcache.document.aquasynth.sound_claims", document!.Type); - Assert.Equal("cultcache/aquasynth/sound-claims.v1", document.Schema); + Assert.Equal(CultCachePatchDocumentCatalog.Type, document.Type); + Assert.Equal(CultCachePatchDocumentCatalog.Schema, document.Schema); Assert.Equal(1, document.Version); - Assert.Equal(LibraryEntryCount(root), document.PatchDatabase.Entries.Count); + Assert.Equal(LibraryEntryCount(root), document.PatchDatabase.Entries.Length); Assert.Contains(document.PatchClaims, claim => claim.Id == "dx7/public-domain-mc-mm-5-3/aquasynth" && claim.Tier == "parity"); Assert.Contains(document.PatchClaims, claim => claim.Id == "zyn/project-pad-texture/aquasynth" && claim.Reference.SynthOrSource.Contains("ZynAddSubFX", StringComparison.Ordinal)); Assert.Contains(document.SpeechClaims, claim => claim.Id == "speech/espeak-ng-tiny-workout" && claim.Target.AnatomyOrProfile.Contains("human", StringComparison.OrdinalIgnoreCase)); @@ -26,11 +22,10 @@ public sealed class CultCachePatchDocumentTests } [Fact] - public void EverySeriousClaimNamesAReferenceAndReceiptSurface() + public async Task EverySeriousClaimNamesAReferenceAndReceiptSurface() { - var document = JsonSerializer.Deserialize( - File.ReadAllText(Path.Combine(RepositoryRoot(), "patches", "aquasynth-patch-cultcache.json")), - new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!; + var document = await CultCachePatchDocumentStore.ReadAsync( + Path.Combine(RepositoryRoot(), "patches", "aquasynth-patch-cultcache.cc")); foreach (var claim in document.PatchClaims) { @@ -54,11 +49,10 @@ public sealed class CultCachePatchDocumentTests } [Fact] - public void CultCachePatchClaimsCoverReferenceRebuildCatalog() + public async Task CultCachePatchClaimsCoverReferenceRebuildCatalog() { - var document = JsonSerializer.Deserialize( - File.ReadAllText(Path.Combine(RepositoryRoot(), "patches", "aquasynth-patch-cultcache.json")), - new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!; + var document = await CultCachePatchDocumentStore.ReadAsync( + Path.Combine(RepositoryRoot(), "patches", "aquasynth-patch-cultcache.cc")); var claimIds = document.PatchClaims.Select(claim => claim.Id).ToHashSet(StringComparer.Ordinal); foreach (var rebuild in ReferenceRebuildCatalog.All()) @@ -67,6 +61,18 @@ public sealed class CultCachePatchDocumentTests } } + [Fact] + public async Task CheckedInCultCacheFileMatchesTypedCatalog() + { + var fromFile = await CultCachePatchDocumentStore.ReadAsync( + Path.Combine(RepositoryRoot(), "patches", "aquasynth-patch-cultcache.cc")); + var fromCatalog = CultCachePatchDocumentCatalog.CreateDefault(); + + Assert.Equal(fromCatalog.PatchDatabase.Entries, fromFile.PatchDatabase.Entries); + Assert.Equal(fromCatalog.PatchClaims.Select(claim => claim.Id), fromFile.PatchClaims.Select(claim => claim.Id)); + Assert.Equal(fromCatalog.SpeechClaims.Select(claim => claim.Id), fromFile.SpeechClaims.Select(claim => claim.Id)); + } + private static int LibraryEntryCount(string root) => File.ReadLines(Path.Combine(root, "patches", "library.yaml")) .Count(line => line.TrimStart().StartsWith("- path:", StringComparison.Ordinal));