diff --git a/Cargo.toml b/Cargo.toml index 10b4341..da49d47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = ["core", "pattern", "swang", "ui-core", "cockpit", "cli", "plugin", " # the hard-constraint-contract proposal); excluded for the same reason — # production builds, clippy, and CI never touch it, and its solver # dependencies never enter the workspace tree. -exclude = ["fuzz", "lab"] +exclude = ["fuzz", "lab", "census"] resolver = "2" [workspace.package] diff --git a/census/.gitignore b/census/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/census/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/census/Cargo.toml b/census/Cargo.toml new file mode 100644 index 0000000..2d0881a --- /dev/null +++ b/census/Cargo.toml @@ -0,0 +1,29 @@ +# Isolated read-only corpus census (real-corpus grounding, ADR-0010 isolation +# precedent like `lab/` and `fuzz/`). Deliberately NOT a workspace member: it is +# ops/analysis tooling that reads a corpus + its source tabs and emits a health +# report. Production builds, clippy, and CI never touch it; its only path +# dependency is `griff-core`, read-only. It changes no corpus data. + +[package] +name = "griff-corpus-census" +version = "0.0.0" +publish = false +edition = "2021" +rust-version = "1.92" + +[[bin]] +name = "census" +path = "src/main.rs" + +[dependencies] +serde = { version = "1", features = ["derive"] } +serde_json = "1" + +[dependencies.griff-core] +path = "../core" + +[lints.rust] +unsafe_code = "forbid" + +[lints.clippy] +all = { level = "deny", priority = -1 } diff --git a/census/corpus-health.json b/census/corpus-health.json new file mode 100644 index 0000000..174cfb3 --- /dev/null +++ b/census/corpus-health.json @@ -0,0 +1,1198 @@ +{ + "input_digest": "6955b33bdfa27e712ae64b12be8b3b0b4c509a496377c523331ea769e73e9c4e", + "manifests": [ + { + "path": "ingest/manifest.json", + "schema_version": 8, + "chunks": 9687, + "groups": 400 + }, + { + "path": "manifest.json", + "schema_version": 8, + "chunks": 220, + "groups": 5 + } + ], + "counts": { + "chunk_files": 9907, + "chunk_parse_errors": 0, + "manifest_chunk_records": 9907, + "unique_referenced_filenames": 400, + "tab_files": 410 + }, + "manifest_reconciliation": { + "files_covered_by_a_manifest": 9907, + "files_not_in_any_manifest": 0, + "manifest_ids_without_a_file": 0 + }, + "source_reconciliation": { + "matched_sources": 400, + "referenced_sources": [ + "A Lot Like Birds - A Satire Of A Satire Is Tiring.gpx", + "A Lot Like Birds - Always Burning Always Dark.gp5", + "A Lot Like Birds - Connector (ver 2 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Connector.gp5", + "A Lot Like Birds - Divisi.gp5", + "A Lot Like Birds - For Shelley Unheard.gp5", + "A Lot Like Birds - From Moon To Son.gp5", + "A Lot Like Birds - Further Below.gp5", + "A Lot Like Birds - Good Soil Bad Seeds.gp5", + "A Lot Like Birds - Hand Over Mouth Over And Over.gp5", + "A Lot Like Birds - Infinite Chances.gp5", + "A Lot Like Birds - Kuroi Ledge (ver 2 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Kuroi Ledge.gp5", + "A Lot Like Birds - Myth Of Lasting Sympathy.gp5", + "A Lot Like Birds - Next To Ungodliness (ver 2 by edwinal0504).gpx", + "A Lot Like Birds - Next To Ungodliness (ver 3 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Next To Ungodliness.gp5", + "A Lot Like Birds - No Attention For Solved Puzzles.gp5", + "A Lot Like Birds - No Nature.gp5", + "A Lot Like Birds - No Nurture.gp5", + "A Lot Like Birds - Orange Time Machines Care.gpx", + "A Lot Like Birds - Recluse.gp5", + "A Lot Like Birds - Sesame Street Is No Place For Me.gp5", + "A Lot Like Birds - Shaking Of The Frame.gp5", + "A Lot Like Birds - The Smoother The Stone.gp5", + "A Lot Like Birds - The Sound Of Us.gp5", + "A Lot Like Birds - Think Dirty Out Loud.gpx", + "A Lot Like Birds - Trace The Lines.gp5", + "Dance Gavin Dance - 12 Hours 630 Miles (ver 2 by patman1416).gp5", + "Dance Gavin Dance - 12 Hours 630 Miles.gp5", + "Dance Gavin Dance - Alex English (ver 2 by CrashAshes43).gpx", + "Dance Gavin Dance - Alex English (ver 3 by funkyrocker24).gp5", + "Dance Gavin Dance - And I Told Them I Invented Times New Roman.gp5", + "Dance Gavin Dance - Antlion.gp5", + "Dance Gavin Dance - Attack Of The Dashing Young And Bold.gp5", + "Dance Gavin Dance - Awkward.gp5", + "Dance Gavin Dance - Back On Deck.gp5", + "Dance Gavin Dance - Betrayed By The Game (ver 2 by mikoyeahyeah).gpx", + "Dance Gavin Dance - Betrayed By The Game.gp5", + "Dance Gavin Dance - Blood Wolf (ver 2 by Mage_Gage).gp", + "Dance Gavin Dance - Blood Wolf.gp5", + "Dance Gavin Dance - Bloodsucker (ver 2 by RiseAgainst34).gp", + "Dance Gavin Dance - Bloodsucker (ver 3 by ed.garnett28).gp", + "Dance Gavin Dance - Bloodsucker.gp5", + "Dance Gavin Dance - Blue Dream (ver 2 by Lem0nz).gp5", + "Dance Gavin Dance - Blue Dream.gp5", + "Dance Gavin Dance - Born To Fail (ver 2 by president100).gp5", + "Dance Gavin Dance - Born To Fail.gp", + "Dance Gavin Dance - Buffalo (ver 2 by jakebohn81).gpx", + "Dance Gavin Dance - Buffalo.gpx", + "Dance Gavin Dance - Burning Down The Nicotine Armoire.gp5", + "Dance Gavin Dance - Calentamiento Global.gp5", + "Dance Gavin Dance - Care (ver 2 by president100).gp5", + "Dance Gavin Dance - Care (ver 3 by TheLoEnd).gp", + "Dance Gavin Dance - Care.gp", + "Dance Gavin Dance - Carl Barker (ver 2 by rudy_rubber).gp", + "Dance Gavin Dance - Carl Barker.gp4", + "Dance Gavin Dance - Carve.gpx", + "Dance Gavin Dance - Caviar (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Caviar.gp5", + "Dance Gavin Dance - Chocolate Jackalope.gp", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 2 by mikoyeahyeah).gpx", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 3 by lacesup).gp", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 4 by juskiwmatt).gp5", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 5 by president100).gp5", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise.gpx", + "Dance Gavin Dance - Count Bassy.gp5", + "Dance Gavin Dance - Cream Of The Crop.gp5", + "Dance Gavin Dance - Current Events.gp5", + "Dance Gavin Dance - Death Of A Strawberry.gp", + "Dance Gavin Dance - Deception (ver 2 by lilgstryker).gp5", + "Dance Gavin Dance - Deception.gpx", + "Dance Gavin Dance - Die Another Day.gp5", + "Dance Gavin Dance - Doom And Gloom.gp", + "Dance Gavin Dance - Eagle Vs Crows (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Eagle Vs Crows.gp5", + "Dance Gavin Dance - Elder Goose.gp5", + "Dance Gavin Dance - Ember.gp5", + "Dance Gavin Dance - Evaporate (ver 2 by president100).gp5", + "Dance Gavin Dance - Evaporate (ver 3 by RiseAgainst34).gp", + "Dance Gavin Dance - Evaporate.gpx", + "Dance Gavin Dance - Exposed.gpx", + "Dance Gavin Dance - Feels Bad Man.gp5", + "Dance Gavin Dance - Flash (ver 2 by RiseAgainst34).gp", + "Dance Gavin Dance - Flash.gp5", + "Dance Gavin Dance - Flossie Dickey Bounce.gp5", + "Dance Gavin Dance - For The Jeers.gp5", + "Dance Gavin Dance - Frozen One.gp5", + "Dance Gavin Dance - Gospel Burnout.gp5", + "Dance Gavin Dance - Hair Song.gp5", + "Dance Gavin Dance - Happiness (ver 2 by dylanure2005).gp5", + "Dance Gavin Dance - Happiness.gpx", + "Dance Gavin Dance - Have A Great Life.gp5", + "Dance Gavin Dance - Head Hunter (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Heat Seeking Ghost Of Sex (ver 2 by kingshaunicus).gp5", + "Dance Gavin Dance - Heat Seeking Ghost Of Sex.gp5", + "Dance Gavin Dance - Here Comes The Winner.gp5", + "Dance Gavin Dance - Holy Ghost Spirit.gp5", + "Dance Gavin Dance - Honey Revenge.gp5", + "Dance Gavin Dance - Hot Water On Wool (ver 2 by jakebohn81).gpx", + "Dance Gavin Dance - Hot Water On Wool.gp4", + "Dance Gavin Dance - Inspire The Liars.gp", + "Dance Gavin Dance - Into The Sunset.gp5", + "Dance Gavin Dance - Its Safe To Say You Dig The Backseat (ver 2).gp5", + "Dance Gavin Dance - Its Safe To Say You Dig The Backseat.gp5", + "Dance Gavin Dance - Jesus H Macy.gp4", + "Dance Gavin Dance - Legend.gp5", + "Dance Gavin Dance - Lemon Meringue Tie (ver 2 by kucharz89).gp5", + "Dance Gavin Dance - Lemon Meringue Tie (ver 3 by GonchDog).gp5", + "Dance Gavin Dance - Lemon Meringue Tie (ver 4 by ed.garnett28).gp", + "Dance Gavin Dance - Lemon Meringue Tie (ver 5 by mando2793).gpx", + "Dance Gavin Dance - Lemon Meringue Tie.gp5", + "Dance Gavin Dance - Long Nights In Jail (ver 2 by raviolimaster).gp5", + "Dance Gavin Dance - Long Nights In Jail.gp5", + "Dance Gavin Dance - Lost.gpx", + "Dance Gavin Dance - Lyrics Lie (ver 2 by president100).gp5", + "Dance Gavin Dance - Lyrics Lie.gp5", + "Dance Gavin Dance - Man Of The Year.gpx", + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 2 by kucharz89).gp5", + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 3 by 93dric).gp5", + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine.gp5", + "Dance Gavin Dance - Midnight Crusade (ver 2).gp5", + "Dance Gavin Dance - Midnight Crusade (ver 3 by Dudealy).gpx", + "Dance Gavin Dance - Midnight Crusade (ver 4 by president100).gp5", + "Dance Gavin Dance - Midnight Crusade (ver 5 by TheLoEnd).gp", + "Dance Gavin Dance - Midnight Crusade.gpx", + "Dance Gavin Dance - Nasa (ver 2 by lacesup).gpx", + "Dance Gavin Dance - Nasa (ver 3 by jakebohn81).gpx", + "Dance Gavin Dance - Nasa.gp4", + "Dance Gavin Dance - Need Money.gp5", + "Dance Gavin Dance - Night Sway.gp5", + "Dance Gavin Dance - Nothing Shameful (ver 2 by president100).gp5", + "Dance Gavin Dance - Nothing Shameful.gpx", + "Dance Gavin Dance - On The Run.gpx", + "Dance Gavin Dance - One In A Million (ver 2 by Igor0400).gp", + "Dance Gavin Dance - One In A Million (ver 3 by president100).gp5", + "Dance Gavin Dance - One Mans Cringe.gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 2 by TalkingToAngels).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 2).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 3).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 4 by oreopimp44).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 5 by mgttg47).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North.gp5", + "Dance Gavin Dance - Parallels.gp5", + "Dance Gavin Dance - Parody Catharsis (ver 2 by lt22).gp", + "Dance Gavin Dance - Parody Catharsis (ver 3 by setsy).gp", + "Dance Gavin Dance - Parody Catharsis (ver 4 by president100).gp5", + "Dance Gavin Dance - Parody Catharsis.gp5", + "Dance Gavin Dance - People You Know.gp5", + "Dance Gavin Dance - Perfect.gpx", + "Dance Gavin Dance - Philosopher King (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Philosopher King.gp", + "Dance Gavin Dance - Polka Dot Dobbins (ver 2 by raviolimaster).gp5", + "Dance Gavin Dance - Polka Dot Dobbins.gp5", + "Dance Gavin Dance - Pop Off.gp", + "Dance Gavin Dance - Pounce Bounce.gp5", + "Dance Gavin Dance - Powder To The People.gp5", + "Dance Gavin Dance - Pray To God For Your Mother.gp5", + "Dance Gavin Dance - Prisoner (ver 2 by Medeses).gp", + "Dance Gavin Dance - Prisoner (ver 3 by president100).gp5", + "Dance Gavin Dance - Prisoner.gp", + "Dance Gavin Dance - Privilously Poncheezied (ver 2 by edwinal0504).gpx", + "Dance Gavin Dance - Privilously Poncheezied.gp5", + "Dance Gavin Dance - Purple Reign.gp5", + "Dance Gavin Dance - Rock Solid.gp5", + "Dance Gavin Dance - Say Hi.gp5", + "Dance Gavin Dance - Self-Trepanation.gpx", + "Dance Gavin Dance - Semi-Charmed Life.gp5", + "Dance Gavin Dance - Shark Dad.gp", + "Dance Gavin Dance - Shark Dad.gpx", + "Dance Gavin Dance - Shelf Life (ver 2 by president100).gp5", + "Dance Gavin Dance - Shelf Life.gpx", + "Dance Gavin Dance - Skyhook (ver 2 by maxtricano).gp", + "Dance Gavin Dance - Skyhook.gp", + "Dance Gavin Dance - Slouch.gp5", + "Dance Gavin Dance - Son Of Robot (ver 2 by president100).gp5", + "Dance Gavin Dance - Son Of Robot.gp5", + "Dance Gavin Dance - Speed Demon.gp5", + "Dance Gavin Dance - Spooks.gp5", + "Dance Gavin Dance - Story Of My Bros.gp5", + "Dance Gavin Dance - Straight From The Heart.gp5", + "Dance Gavin Dance - Strawberry Andre (ver 2 by GonchDog).gp5", + "Dance Gavin Dance - Strawberry Andre.gp5", + "Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 2 by HectorDaniel).gpx", + "Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 3 by gjikolp).gp", + "Dance Gavin Dance - Strawberry Swisher Pt 2.gp5", + "Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 2 by marcellus97).gpx", + "Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 3 by senorkatana11).gp", + "Dance Gavin Dance - Strawberry Swisher Pt 3.gpx", + "Dance Gavin Dance - Strawberrys Wake (ver 2 by lriax).gp5", + "Dance Gavin Dance - Strawberrys Wake (ver 3 by president100).gp5", + "Dance Gavin Dance - Strawberrys Wake.gp", + "Dance Gavin Dance - Stroke God Millionaire (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Stroke God Millionaire.gp5", + "Dance Gavin Dance - Summertime Gladness.gpx", + "Dance Gavin Dance - Surprise Im From Cuba Everyone Else Has One Brain.gp", + "Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain (ver 2 by GonchDog).gp5", + "Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain.gp5", + "Dance Gavin Dance - Suspended In This Disaster (ver 2 by president100).gp5", + "Dance Gavin Dance - Suspended In This Disaster.gpx", + "Dance Gavin Dance - Swallowed By Eternity.gp5", + "Dance Gavin Dance - Swan Soup.gp5", + "Dance Gavin Dance - Synergy (ver 2 by lucascocker5).gp5", + "Dance Gavin Dance - Synergy (ver 3 by senorkatana11).gp", + "Dance Gavin Dance - Synergy.gp5", + "Dance Gavin Dance - Thats What I Like.gpx", + "Dance Gavin Dance - The Backwards Pumpkin Song (ver 2 by TheClincher).gp5", + "Dance Gavin Dance - The Backwards Pumpkin Song (ver 3 by MagentaMalice).gp5", + "Dance Gavin Dance - The Backwards Pumpkin Song.gp5", + "Dance Gavin Dance - The Cuddler.gpx", + "Dance Gavin Dance - The Ghost Of Billy Royalton (ver 2 by m.najera.ve).gp5", + "Dance Gavin Dance - The Ghost Of Billy Royalton.gp5", + "Dance Gavin Dance - The Importance Of Cocaine.gp5", + "Dance Gavin Dance - The Jiggler.gp5", + "Dance Gavin Dance - The Rattler.gp5", + "Dance Gavin Dance - The Robot Vs Heroin Battle Of Vietnam.gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 1.gp", + "Dance Gavin Dance - The Robot With Human Hair Part 2 (ver 2 by Thomasoman).gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 2.gp3", + "Dance Gavin Dance - The Robot With Human Hair Part 2.gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 2 by tar pit trap).gp4", + "Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 3 by m.najera.ve).gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 3.gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 4.gpx", + "Dance Gavin Dance - Three Wishes.gp5", + "Dance Gavin Dance - Thug City.gp5", + "Dance Gavin Dance - Tidal Waves Breakfast Lunch Dinner.gp5", + "Dance Gavin Dance - Tree Village (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Tree Village.gp5", + "Dance Gavin Dance - Turn Off The Lights Im Watching Back To The Future Pt Ii.gp", + "Dance Gavin Dance - Turn Off The Lights Im Watching Back To The Future.gp5", + "Dance Gavin Dance - Two Secret Weapons.gp5", + "Dance Gavin Dance - Uneasy Hearts Weigh The Most (ver 2).gp", + "Dance Gavin Dance - Uneasy Hearts Weigh The Most.gp5", + "Dance Gavin Dance - Untitled.gp5", + "Dance Gavin Dance - Variation (ver 2 by Dio10101).gpx", + "Dance Gavin Dance - Variation.gpx", + "Dance Gavin Dance - War Machine.gp", + "Dance Gavin Dance - We Own The Night (ver 2 by mstumpfig).gpx", + "Dance Gavin Dance - We Own The Night.gp5", + "Dance Gavin Dance - Young Robot (ver 2 by josh-josh-josh).gpx", + "Dance Gavin Dance - Young Robot (ver 3 by president100).gp5", + "Dance Gavin Dance - Young Robot.gpx", + "Ghost - Kaisarion.gp", + "Hail The Sun - 1109.gp5", + "Hail The Sun - Anti-Eulogy I Hope You Stay Dead.gp", + "Hail The Sun - Anti-Eulogy.gp5", + "Hail The Sun - Black Serotonin (ver 2 by thursday21987).gp", + "Hail The Sun - Black Serotonin.gp5", + "Hail The Sun - Bound.gp", + "Hail The Sun - Chunker (ver 2 by ry.schenck).gp", + "Hail The Sun - Chunker.gp", + "Hail The Sun - Cosmic Narcissism (ver 2 by thursday21987).gp", + "Hail The Sun - Cosmic Narcissism.gp", + "Hail The Sun - Cosmic Narcissism.gp5", + "Hail The Sun - Dead Messages.gp", + "Hail The Sun - Disappearing Syndrome (ver 2 by thursday21987).gp", + "Hail The Sun - Disappearing Syndrome.gp", + "Hail The Sun - Domino.gp", + "Hail The Sun - Eight-Ball Coroners Pocket.gpx", + "Hail The Sun - Entertainment Lies.gp5", + "Hail The Sun - Falling On Deaf Ears.gp", + "Hail The Sun - Glass Half Empty.gpx", + "Hail The Sun - Hanging Revelation.gp", + "Hail The Sun - Human Target Practice (ver 2 by thursday21987).gp", + "Hail The Sun - Human Target Practice.gp", + "Hail The Sun - Jane Doe.gp", + "Hail The Sun - Mental Knife.gpx", + "Hail The Sun - Misfire.gp5", + "Hail The Sun - Missed Injections (ver 2 by thursday21987).gp", + "Hail The Sun - Missed Injections.gp", + "Hail The Sun - Mourning Sickness (ver 2 by thursday21987).gp", + "Hail The Sun - Mourning Sickness.gp", + "Hail The Sun - Never Kill A Mouse Let It Kill Itself (ver 2).gp5", + "Hail The Sun - Never Kill A Mouse Let It Kill Itself.gp4", + "Hail The Sun - Parasitic Cleanse.gp", + "Hail The Sun - Ready Or Not There I Go.gp5", + "Hail The Sun - Relax Divide (ver 2 by dayamira).gp", + "Hail The Sun - Relax Divide (ver 3 by thursday21987).gp", + "Hail The Sun - Relax Divide.gp", + "Hail The Sun - Relax Divide.gp5", + "Hail The Sun - Rolling Out The Red Carpet (ver 2 by thursday21987).gp", + "Hail The Sun - Rolling Out The Red Carpet.gpx", + "Hail The Sun - Spite.gpx", + "Hail The Sun - Theres Plenty Of Fish In The Sea Too Bad Youre Not A Fish.gpx", + "Hail The Sun - Will They Blame Me If You Go Disappearing (ver 2 by Wicked Strum).gp5", + "Hail The Sun - Will They Blame Me If You Go Disappearing.gp5", + "Hail The Sun - Words Of Gratitude.gp5", + "Sianvar - 1100 Days.gpx", + "Sianvar - Chest Pressure.gp5", + "Sianvar - Omniphobia.gp", + "Sianvar - Virtual Vain.gp5", + "Underoath - A Boy Brushed Red Living In Black And White (ver 2 by kiefermatot).gp4", + "Underoath - A Boy Brushed Red Living In Black And White (ver 3 by pnkr0cker).gp5", + "Underoath - A Boy Brushed Red Living In Black And White.gp4", + "Underoath - A Divine Eradication.gp5", + "Underoath - A Fault Line A Fault Of Mine.gp5", + "Underoath - A Message For Adrienne (ver 2).gp5", + "Underoath - A Message For Adrienne.gp4", + "Underoath - A Moment Suspended In Time.gp5", + "Underoath - Act Of Depression.gp5", + "Underoath - All The Love Is Gone.gp5", + "Underoath - Alone In December (ver 2 by Gil310).gp5", + "Underoath - Alone In December (ver 3 by Lil-gzlz96).gpx", + "Underoath - Alone In December.gp5", + "Underoath - And I Dreamt Of You.gp5", + "Underoath - Angel Below.gp4", + "Underoath - Angels Below.gp5", + "Underoath - Breathing In A New Mentality (ver 2 by zachemtak).gp5", + "Underoath - Breathing In A New Mentality.gp5", + "Underoath - Casting Such A Thin Shadow (ver 2 by bloodlustx36).gp5", + "Underoath - Casting Such A Thin Shadow (ver 3 by js021).gp", + "Underoath - Casting Such A Thin Shadow.gp5", + "Underoath - Catch Myself Catching Myself.gp5", + "Underoath - Cries Of The Past.gp5", + "Underoath - Desolate Earth The End Is Here.gp5", + "Underoath - Desperate Times Desperate Measures (ver 2 by bloodlustx36).gp5", + "Underoath - Desperate Times Desperate Measures.gp5", + "Underoath - Down Set Go (ver 2 by LookIntotheAir).gp5", + "Underoath - Down Set Go.gp5", + "Underoath - Driftwood.gp5", + "Underoath - Everyone Looks So Good From Here (ver 2 by seanwatson18).gp5", + "Underoath - Everyone Looks So Good From Here.gp4", + "Underoath - Heart Of Stone.gp4", + "Underoath - Hold Your Breath.gpx", + "Underoath - I Dont Feel Very Receptive Today.gp4", + "Underoath - I Gave Up.gpx", + "Underoath - I Got 10 Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4", + "Underoath - I Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp", + "Underoath - Illuminator (ver 2 by swandive).gpx", + "Underoath - Illuminator (ver 3 by desoulate).gp5", + "Underoath - Illuminator.gp5", + "Underoath - Im Content With Losing (ver 2 by kikiu).gp5", + "Underoath - Im Content With Losing.gp4", + "Underoath - In Completion.gp5", + "Underoath - In Division.gp5", + "Underoath - In Motion.gpx", + "Underoath - In Regards To Myself (ver 2 by re_man182).gp5", + "Underoath - In Regards To Myself (ver 3 by LookIntotheAir).gp5", + "Underoath - In Regards To Myself (ver 4 by grizzlyfs92).gp", + "Underoath - In Regards To Myself.gp4", + "Underoath - In Regards To Myself.gp5", + "Underoath - Innocence Stolen.gp4", + "Underoath - Its Dangerous Business Walking Out Your Front Door.gp4", + "Underoath - Its Dangerous Business Walking Out Your Front Door.gp5", + "Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack (ver 2 by LookIntotheAir).gp5", + "Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4", + "Underoath - Last (ver 2 by catalan123).gp5", + "Underoath - Last.gp5", + "Underoath - Letting Go Of Tonight.gp5", + "Underoath - Moving For The Sake Of Motion.gp5", + "Underoath - My Deteriorating Incline.gp5", + "Underoath - Never Meant To Break Your Heart (ver 2 by @xel).gp5", + "Underoath - Never Meant To Break Your Heart.gp4", + "Underoath - No Frame.gpx", + "Underoath - On My Teeth (ver 2 by JackCadenhead).gpx", + "Underoath - On My Teeth (ver 3 by desoulate).gp5", + "Underoath - On My Teeth.gpx", + "Underoath - Paper Lung.gp5", + "Underoath - Rapture.gpx", + "Underoath - Reinventing Your Exit (ver 2 by alexisonfire21).gp4", + "Underoath - Reinventing Your Exit (ver 3 by _Doggy_).gp5", + "Underoath - Reinventing Your Exit.gp4", + "Underoath - Returning Empty Handed.gp5", + "Underoath - Short Of Daybreak (ver 2 by callums_revenge).gp5", + "Underoath - Short Of Daybreak (ver 3 by gerald.gonzalezvazquez).gpx", + "Underoath - Short Of Daybreak.gp5", + "Underoath - Some Will Seek Forgiveness Others Escape (ver 2 by Jcrutch86).gp5", + "Underoath - Some Will Seek Forgiveness Others Escape.gp5", + "Underoath - Some Will Seek Forgiveness Others Escape.gpx", + "Underoath - The Impact Of Reason.gp", + "Underoath - The Only Survivor Was Miraculously Unharmed.gp4", + "Underoath - There Could Be Nothing After This.gp5", + "Underoath - Those Who Reach An Endless Trail.gp", + "Underoath - To Whom It May Concern (ver 2 by n.schulz29).gpx", + "Underoath - To Whom It May Concern.gp5", + "Underoath - Too Bright To See Too Loud To Hear (ver 2 by jayman5671).gp5", + "Underoath - Too Bright To See Too Loud To Hear.gp5", + "Underoath - Unsound.gp5", + "Underoath - Vacant Mouth.gp5", + "Underoath - Watch Me Die.gp4", + "Underoath - When The Sun Sleeps (ver 2 by under218).gp5", + "Underoath - When The Sun Sleeps (ver 3 by LookIntotheAir).gp4", + "Underoath - When The Sun Sleeps (ver 4 by sk8ter4life).gp5", + "Underoath - When The Sun Sleeps (ver 5 by js021).gp", + "Underoath - When The Sun Sleeps.gp4", + "Underoath - Who Will Guard The Guardians.gp5", + "Underoath - Writing On The Walls (ver 2).gp5", + "Underoath - Writing On The Walls (ver 3 by re_man182).gp5", + "Underoath - Writing On The Walls (ver 4 by decasta).gp5", + "Underoath - Writing On The Walls.gp4", + "Underoath - Young And Aspiring (ver 2 by _Doggy_).gp5", + "Underoath - Young And Aspiring.gp4", + "Underoath - Youre Ever So Inviting (ver 2 by josh-josh-josh).gpx", + "Underoath - Youre Ever So Inviting.gp5", + "Wolf & Bear - Deleto.gp5", + "Wolf & Bear - Sight (ver 2 by ezekiela1996).gp5", + "Wolf & Bear - Street Rat.gp", + "Wolf & Bear - Theres No Dust In The City.gp", + "Wolf & Bear - Twisted Tongues.gpx" + ], + "missing_sources": [], + "ambiguous_sources": [], + "unreferenced_tabs": [ + "tabs/A Lot Like Birds - Atoms In Evening.gp5", + "tabs/Dance Gavin Dance - Alex English.gp5", + "tabs/Dance Gavin Dance - Head Hunter.gp", + "tabs/Dance Gavin Dance - One In A Million.gp", + "tabs/Dance Gavin Dance - The Robot With Human Hair Part 4 (ver 2 by MagentaMalice).gp5", + "tabs/Hail The Sun - Chunker.gpx", + "tabs/Underoath - Anyone Can Dig A Hole But It Takes A Real Man To Call It Home.gpx", + "tabs/Underoath - Reversal.gp5", + "tabs/Wolf & Bear - Quick Sip 84.gp", + "tabs/Wolf & Bear - Sight.gp5" + ] + }, + "v9_coverage": { + "sha256_present": 0, + "track_index_present": 0, + "total_chunks": 9907 + }, + "v10_readiness": { + "song_id_field_in_schema": false, + "distinct_works_estimated": 257, + "multi_transcription_works": [ + { + "work": "dance gavin dance - open your eyes and look north", + "files": [ + "Dance Gavin Dance - Open Your Eyes And Look North (ver 2 by TalkingToAngels).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 2).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 3).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 4 by oreopimp44).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North (ver 5 by mgttg47).gp5", + "Dance Gavin Dance - Open Your Eyes And Look North.gp5" + ] + }, + { + "work": "dance gavin dance - chucky vs the giant tortoise", + "files": [ + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 2 by mikoyeahyeah).gpx", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 3 by lacesup).gp", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 4 by juskiwmatt).gp5", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 5 by president100).gp5", + "Dance Gavin Dance - Chucky Vs The Giant Tortoise.gpx" + ] + }, + { + "work": "dance gavin dance - lemon meringue tie", + "files": [ + "Dance Gavin Dance - Lemon Meringue Tie (ver 2 by kucharz89).gp5", + "Dance Gavin Dance - Lemon Meringue Tie (ver 3 by GonchDog).gp5", + "Dance Gavin Dance - Lemon Meringue Tie (ver 4 by ed.garnett28).gp", + "Dance Gavin Dance - Lemon Meringue Tie (ver 5 by mando2793).gpx", + "Dance Gavin Dance - Lemon Meringue Tie.gp5" + ] + }, + { + "work": "dance gavin dance - midnight crusade", + "files": [ + "Dance Gavin Dance - Midnight Crusade (ver 2).gp5", + "Dance Gavin Dance - Midnight Crusade (ver 3 by Dudealy).gpx", + "Dance Gavin Dance - Midnight Crusade (ver 4 by president100).gp5", + "Dance Gavin Dance - Midnight Crusade (ver 5 by TheLoEnd).gp", + "Dance Gavin Dance - Midnight Crusade.gpx" + ] + }, + { + "work": "underoath - in regards to myself", + "files": [ + "Underoath - In Regards To Myself (ver 2 by re_man182).gp5", + "Underoath - In Regards To Myself (ver 3 by LookIntotheAir).gp5", + "Underoath - In Regards To Myself (ver 4 by grizzlyfs92).gp", + "Underoath - In Regards To Myself.gp4", + "Underoath - In Regards To Myself.gp5" + ] + }, + { + "work": "underoath - when the sun sleeps", + "files": [ + "Underoath - When The Sun Sleeps (ver 2 by under218).gp5", + "Underoath - When The Sun Sleeps (ver 3 by LookIntotheAir).gp4", + "Underoath - When The Sun Sleeps (ver 4 by sk8ter4life).gp5", + "Underoath - When The Sun Sleeps (ver 5 by js021).gp", + "Underoath - When The Sun Sleeps.gp4" + ] + }, + { + "work": "dance gavin dance - parody catharsis", + "files": [ + "Dance Gavin Dance - Parody Catharsis (ver 2 by lt22).gp", + "Dance Gavin Dance - Parody Catharsis (ver 3 by setsy).gp", + "Dance Gavin Dance - Parody Catharsis (ver 4 by president100).gp5", + "Dance Gavin Dance - Parody Catharsis.gp5" + ] + }, + { + "work": "hail the sun - relax divide", + "files": [ + "Hail The Sun - Relax Divide (ver 2 by dayamira).gp", + "Hail The Sun - Relax Divide (ver 3 by thursday21987).gp", + "Hail The Sun - Relax Divide.gp", + "Hail The Sun - Relax Divide.gp5" + ] + }, + { + "work": "underoath - writing on the walls", + "files": [ + "Underoath - Writing On The Walls (ver 2).gp5", + "Underoath - Writing On The Walls (ver 3 by re_man182).gp5", + "Underoath - Writing On The Walls (ver 4 by decasta).gp5", + "Underoath - Writing On The Walls.gp4" + ] + }, + { + "work": "a lot like birds - next to ungodliness", + "files": [ + "A Lot Like Birds - Next To Ungodliness (ver 2 by edwinal0504).gpx", + "A Lot Like Birds - Next To Ungodliness (ver 3 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Next To Ungodliness.gp5" + ] + }, + { + "work": "dance gavin dance - bloodsucker", + "files": [ + "Dance Gavin Dance - Bloodsucker (ver 2 by RiseAgainst34).gp", + "Dance Gavin Dance - Bloodsucker (ver 3 by ed.garnett28).gp", + "Dance Gavin Dance - Bloodsucker.gp5" + ] + }, + { + "work": "dance gavin dance - care", + "files": [ + "Dance Gavin Dance - Care (ver 2 by president100).gp5", + "Dance Gavin Dance - Care (ver 3 by TheLoEnd).gp", + "Dance Gavin Dance - Care.gp" + ] + }, + { + "work": "dance gavin dance - evaporate", + "files": [ + "Dance Gavin Dance - Evaporate (ver 2 by president100).gp5", + "Dance Gavin Dance - Evaporate (ver 3 by RiseAgainst34).gp", + "Dance Gavin Dance - Evaporate.gpx" + ] + }, + { + "work": "dance gavin dance - me and zoloft get along just fine", + "files": [ + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 2 by kucharz89).gp5", + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 3 by 93dric).gp5", + "Dance Gavin Dance - Me And Zoloft Get Along Just Fine.gp5" + ] + }, + { + "work": "dance gavin dance - nasa", + "files": [ + "Dance Gavin Dance - Nasa (ver 2 by lacesup).gpx", + "Dance Gavin Dance - Nasa (ver 3 by jakebohn81).gpx", + "Dance Gavin Dance - Nasa.gp4" + ] + }, + { + "work": "dance gavin dance - prisoner", + "files": [ + "Dance Gavin Dance - Prisoner (ver 2 by Medeses).gp", + "Dance Gavin Dance - Prisoner (ver 3 by president100).gp5", + "Dance Gavin Dance - Prisoner.gp" + ] + }, + { + "work": "dance gavin dance - strawberry swisher pt 2", + "files": [ + "Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 2 by HectorDaniel).gpx", + "Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 3 by gjikolp).gp", + "Dance Gavin Dance - Strawberry Swisher Pt 2.gp5" + ] + }, + { + "work": "dance gavin dance - strawberry swisher pt 3", + "files": [ + "Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 2 by marcellus97).gpx", + "Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 3 by senorkatana11).gp", + "Dance Gavin Dance - Strawberry Swisher Pt 3.gpx" + ] + }, + { + "work": "dance gavin dance - strawberrys wake", + "files": [ + "Dance Gavin Dance - Strawberrys Wake (ver 2 by lriax).gp5", + "Dance Gavin Dance - Strawberrys Wake (ver 3 by president100).gp5", + "Dance Gavin Dance - Strawberrys Wake.gp" + ] + }, + { + "work": "dance gavin dance - synergy", + "files": [ + "Dance Gavin Dance - Synergy (ver 2 by lucascocker5).gp5", + "Dance Gavin Dance - Synergy (ver 3 by senorkatana11).gp", + "Dance Gavin Dance - Synergy.gp5" + ] + }, + { + "work": "dance gavin dance - the backwards pumpkin song", + "files": [ + "Dance Gavin Dance - The Backwards Pumpkin Song (ver 2 by TheClincher).gp5", + "Dance Gavin Dance - The Backwards Pumpkin Song (ver 3 by MagentaMalice).gp5", + "Dance Gavin Dance - The Backwards Pumpkin Song.gp5" + ] + }, + { + "work": "dance gavin dance - the robot with human hair part 2", + "files": [ + "Dance Gavin Dance - The Robot With Human Hair Part 2 (ver 2 by Thomasoman).gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 2.gp3", + "Dance Gavin Dance - The Robot With Human Hair Part 2.gp5" + ] + }, + { + "work": "dance gavin dance - the robot with human hair part 3", + "files": [ + "Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 2 by tar pit trap).gp4", + "Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 3 by m.najera.ve).gp5", + "Dance Gavin Dance - The Robot With Human Hair Part 3.gp5" + ] + }, + { + "work": "dance gavin dance - young robot", + "files": [ + "Dance Gavin Dance - Young Robot (ver 2 by josh-josh-josh).gpx", + "Dance Gavin Dance - Young Robot (ver 3 by president100).gp5", + "Dance Gavin Dance - Young Robot.gpx" + ] + }, + { + "work": "hail the sun - cosmic narcissism", + "files": [ + "Hail The Sun - Cosmic Narcissism (ver 2 by thursday21987).gp", + "Hail The Sun - Cosmic Narcissism.gp", + "Hail The Sun - Cosmic Narcissism.gp5" + ] + }, + { + "work": "underoath - a boy brushed red living in black and white", + "files": [ + "Underoath - A Boy Brushed Red Living In Black And White (ver 2 by kiefermatot).gp4", + "Underoath - A Boy Brushed Red Living In Black And White (ver 3 by pnkr0cker).gp5", + "Underoath - A Boy Brushed Red Living In Black And White.gp4" + ] + }, + { + "work": "underoath - alone in december", + "files": [ + "Underoath - Alone In December (ver 2 by Gil310).gp5", + "Underoath - Alone In December (ver 3 by Lil-gzlz96).gpx", + "Underoath - Alone In December.gp5" + ] + }, + { + "work": "underoath - casting such a thin shadow", + "files": [ + "Underoath - Casting Such A Thin Shadow (ver 2 by bloodlustx36).gp5", + "Underoath - Casting Such A Thin Shadow (ver 3 by js021).gp", + "Underoath - Casting Such A Thin Shadow.gp5" + ] + }, + { + "work": "underoath - illuminator", + "files": [ + "Underoath - Illuminator (ver 2 by swandive).gpx", + "Underoath - Illuminator (ver 3 by desoulate).gp5", + "Underoath - Illuminator.gp5" + ] + }, + { + "work": "underoath - on my teeth", + "files": [ + "Underoath - On My Teeth (ver 2 by JackCadenhead).gpx", + "Underoath - On My Teeth (ver 3 by desoulate).gp5", + "Underoath - On My Teeth.gpx" + ] + }, + { + "work": "underoath - reinventing your exit", + "files": [ + "Underoath - Reinventing Your Exit (ver 2 by alexisonfire21).gp4", + "Underoath - Reinventing Your Exit (ver 3 by _Doggy_).gp5", + "Underoath - Reinventing Your Exit.gp4" + ] + }, + { + "work": "underoath - short of daybreak", + "files": [ + "Underoath - Short Of Daybreak (ver 2 by callums_revenge).gp5", + "Underoath - Short Of Daybreak (ver 3 by gerald.gonzalezvazquez).gpx", + "Underoath - Short Of Daybreak.gp5" + ] + }, + { + "work": "underoath - some will seek forgiveness others escape", + "files": [ + "Underoath - Some Will Seek Forgiveness Others Escape (ver 2 by Jcrutch86).gp5", + "Underoath - Some Will Seek Forgiveness Others Escape.gp5", + "Underoath - Some Will Seek Forgiveness Others Escape.gpx" + ] + }, + { + "work": "a lot like birds - connector", + "files": [ + "A Lot Like Birds - Connector (ver 2 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Connector.gp5" + ] + }, + { + "work": "a lot like birds - kuroi ledge", + "files": [ + "A Lot Like Birds - Kuroi Ledge (ver 2 by LPFzCS_LMS).gp5", + "A Lot Like Birds - Kuroi Ledge.gp5" + ] + }, + { + "work": "dance gavin dance - 12 hours 630 miles", + "files": [ + "Dance Gavin Dance - 12 Hours 630 Miles (ver 2 by patman1416).gp5", + "Dance Gavin Dance - 12 Hours 630 Miles.gp5" + ] + }, + { + "work": "dance gavin dance - alex english", + "files": [ + "Dance Gavin Dance - Alex English (ver 2 by CrashAshes43).gpx", + "Dance Gavin Dance - Alex English (ver 3 by funkyrocker24).gp5" + ] + }, + { + "work": "dance gavin dance - betrayed by the game", + "files": [ + "Dance Gavin Dance - Betrayed By The Game (ver 2 by mikoyeahyeah).gpx", + "Dance Gavin Dance - Betrayed By The Game.gp5" + ] + }, + { + "work": "dance gavin dance - blood wolf", + "files": [ + "Dance Gavin Dance - Blood Wolf (ver 2 by Mage_Gage).gp", + "Dance Gavin Dance - Blood Wolf.gp5" + ] + }, + { + "work": "dance gavin dance - blue dream", + "files": [ + "Dance Gavin Dance - Blue Dream (ver 2 by Lem0nz).gp5", + "Dance Gavin Dance - Blue Dream.gp5" + ] + }, + { + "work": "dance gavin dance - born to fail", + "files": [ + "Dance Gavin Dance - Born To Fail (ver 2 by president100).gp5", + "Dance Gavin Dance - Born To Fail.gp" + ] + }, + { + "work": "dance gavin dance - buffalo", + "files": [ + "Dance Gavin Dance - Buffalo (ver 2 by jakebohn81).gpx", + "Dance Gavin Dance - Buffalo.gpx" + ] + }, + { + "work": "dance gavin dance - carl barker", + "files": [ + "Dance Gavin Dance - Carl Barker (ver 2 by rudy_rubber).gp", + "Dance Gavin Dance - Carl Barker.gp4" + ] + }, + { + "work": "dance gavin dance - caviar", + "files": [ + "Dance Gavin Dance - Caviar (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Caviar.gp5" + ] + }, + { + "work": "dance gavin dance - deception", + "files": [ + "Dance Gavin Dance - Deception (ver 2 by lilgstryker).gp5", + "Dance Gavin Dance - Deception.gpx" + ] + }, + { + "work": "dance gavin dance - eagle vs crows", + "files": [ + "Dance Gavin Dance - Eagle Vs Crows (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Eagle Vs Crows.gp5" + ] + }, + { + "work": "dance gavin dance - flash", + "files": [ + "Dance Gavin Dance - Flash (ver 2 by RiseAgainst34).gp", + "Dance Gavin Dance - Flash.gp5" + ] + }, + { + "work": "dance gavin dance - happiness", + "files": [ + "Dance Gavin Dance - Happiness (ver 2 by dylanure2005).gp5", + "Dance Gavin Dance - Happiness.gpx" + ] + }, + { + "work": "dance gavin dance - heat seeking ghost of sex", + "files": [ + "Dance Gavin Dance - Heat Seeking Ghost Of Sex (ver 2 by kingshaunicus).gp5", + "Dance Gavin Dance - Heat Seeking Ghost Of Sex.gp5" + ] + }, + { + "work": "dance gavin dance - hot water on wool", + "files": [ + "Dance Gavin Dance - Hot Water On Wool (ver 2 by jakebohn81).gpx", + "Dance Gavin Dance - Hot Water On Wool.gp4" + ] + }, + { + "work": "dance gavin dance - its safe to say you dig the backseat", + "files": [ + "Dance Gavin Dance - Its Safe To Say You Dig The Backseat (ver 2).gp5", + "Dance Gavin Dance - Its Safe To Say You Dig The Backseat.gp5" + ] + }, + { + "work": "dance gavin dance - long nights in jail", + "files": [ + "Dance Gavin Dance - Long Nights In Jail (ver 2 by raviolimaster).gp5", + "Dance Gavin Dance - Long Nights In Jail.gp5" + ] + }, + { + "work": "dance gavin dance - lyrics lie", + "files": [ + "Dance Gavin Dance - Lyrics Lie (ver 2 by president100).gp5", + "Dance Gavin Dance - Lyrics Lie.gp5" + ] + }, + { + "work": "dance gavin dance - nothing shameful", + "files": [ + "Dance Gavin Dance - Nothing Shameful (ver 2 by president100).gp5", + "Dance Gavin Dance - Nothing Shameful.gpx" + ] + }, + { + "work": "dance gavin dance - one in a million", + "files": [ + "Dance Gavin Dance - One In A Million (ver 2 by Igor0400).gp", + "Dance Gavin Dance - One In A Million (ver 3 by president100).gp5" + ] + }, + { + "work": "dance gavin dance - philosopher king", + "files": [ + "Dance Gavin Dance - Philosopher King (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Philosopher King.gp" + ] + }, + { + "work": "dance gavin dance - polka dot dobbins", + "files": [ + "Dance Gavin Dance - Polka Dot Dobbins (ver 2 by raviolimaster).gp5", + "Dance Gavin Dance - Polka Dot Dobbins.gp5" + ] + }, + { + "work": "dance gavin dance - privilously poncheezied", + "files": [ + "Dance Gavin Dance - Privilously Poncheezied (ver 2 by edwinal0504).gpx", + "Dance Gavin Dance - Privilously Poncheezied.gp5" + ] + }, + { + "work": "dance gavin dance - shark dad", + "files": [ + "Dance Gavin Dance - Shark Dad.gp", + "Dance Gavin Dance - Shark Dad.gpx" + ] + }, + { + "work": "dance gavin dance - shelf life", + "files": [ + "Dance Gavin Dance - Shelf Life (ver 2 by president100).gp5", + "Dance Gavin Dance - Shelf Life.gpx" + ] + }, + { + "work": "dance gavin dance - skyhook", + "files": [ + "Dance Gavin Dance - Skyhook (ver 2 by maxtricano).gp", + "Dance Gavin Dance - Skyhook.gp" + ] + }, + { + "work": "dance gavin dance - son of robot", + "files": [ + "Dance Gavin Dance - Son Of Robot (ver 2 by president100).gp5", + "Dance Gavin Dance - Son Of Robot.gp5" + ] + }, + { + "work": "dance gavin dance - strawberry andre", + "files": [ + "Dance Gavin Dance - Strawberry Andre (ver 2 by GonchDog).gp5", + "Dance Gavin Dance - Strawberry Andre.gp5" + ] + }, + { + "work": "dance gavin dance - stroke god millionaire", + "files": [ + "Dance Gavin Dance - Stroke God Millionaire (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Stroke God Millionaire.gp5" + ] + }, + { + "work": "dance gavin dance - surprise im from cuba everyone has one brain", + "files": [ + "Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain (ver 2 by GonchDog).gp5", + "Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain.gp5" + ] + }, + { + "work": "dance gavin dance - suspended in this disaster", + "files": [ + "Dance Gavin Dance - Suspended In This Disaster (ver 2 by president100).gp5", + "Dance Gavin Dance - Suspended In This Disaster.gpx" + ] + }, + { + "work": "dance gavin dance - the ghost of billy royalton", + "files": [ + "Dance Gavin Dance - The Ghost Of Billy Royalton (ver 2 by m.najera.ve).gp5", + "Dance Gavin Dance - The Ghost Of Billy Royalton.gp5" + ] + }, + { + "work": "dance gavin dance - tree village", + "files": [ + "Dance Gavin Dance - Tree Village (ver 2 by ed.garnett28).gp", + "Dance Gavin Dance - Tree Village.gp5" + ] + }, + { + "work": "dance gavin dance - uneasy hearts weigh the most", + "files": [ + "Dance Gavin Dance - Uneasy Hearts Weigh The Most (ver 2).gp", + "Dance Gavin Dance - Uneasy Hearts Weigh The Most.gp5" + ] + }, + { + "work": "dance gavin dance - variation", + "files": [ + "Dance Gavin Dance - Variation (ver 2 by Dio10101).gpx", + "Dance Gavin Dance - Variation.gpx" + ] + }, + { + "work": "dance gavin dance - we own the night", + "files": [ + "Dance Gavin Dance - We Own The Night (ver 2 by mstumpfig).gpx", + "Dance Gavin Dance - We Own The Night.gp5" + ] + }, + { + "work": "hail the sun - black serotonin", + "files": [ + "Hail The Sun - Black Serotonin (ver 2 by thursday21987).gp", + "Hail The Sun - Black Serotonin.gp5" + ] + }, + { + "work": "hail the sun - chunker", + "files": [ + "Hail The Sun - Chunker (ver 2 by ry.schenck).gp", + "Hail The Sun - Chunker.gp" + ] + }, + { + "work": "hail the sun - disappearing syndrome", + "files": [ + "Hail The Sun - Disappearing Syndrome (ver 2 by thursday21987).gp", + "Hail The Sun - Disappearing Syndrome.gp" + ] + }, + { + "work": "hail the sun - human target practice", + "files": [ + "Hail The Sun - Human Target Practice (ver 2 by thursday21987).gp", + "Hail The Sun - Human Target Practice.gp" + ] + }, + { + "work": "hail the sun - missed injections", + "files": [ + "Hail The Sun - Missed Injections (ver 2 by thursday21987).gp", + "Hail The Sun - Missed Injections.gp" + ] + }, + { + "work": "hail the sun - mourning sickness", + "files": [ + "Hail The Sun - Mourning Sickness (ver 2 by thursday21987).gp", + "Hail The Sun - Mourning Sickness.gp" + ] + }, + { + "work": "hail the sun - never kill a mouse let it kill itself", + "files": [ + "Hail The Sun - Never Kill A Mouse Let It Kill Itself (ver 2).gp5", + "Hail The Sun - Never Kill A Mouse Let It Kill Itself.gp4" + ] + }, + { + "work": "hail the sun - rolling out the red carpet", + "files": [ + "Hail The Sun - Rolling Out The Red Carpet (ver 2 by thursday21987).gp", + "Hail The Sun - Rolling Out The Red Carpet.gpx" + ] + }, + { + "work": "hail the sun - will they blame me if you go disappearing", + "files": [ + "Hail The Sun - Will They Blame Me If You Go Disappearing (ver 2 by Wicked Strum).gp5", + "Hail The Sun - Will They Blame Me If You Go Disappearing.gp5" + ] + }, + { + "work": "underoath - a message for adrienne", + "files": [ + "Underoath - A Message For Adrienne (ver 2).gp5", + "Underoath - A Message For Adrienne.gp4" + ] + }, + { + "work": "underoath - breathing in a new mentality", + "files": [ + "Underoath - Breathing In A New Mentality (ver 2 by zachemtak).gp5", + "Underoath - Breathing In A New Mentality.gp5" + ] + }, + { + "work": "underoath - desperate times desperate measures", + "files": [ + "Underoath - Desperate Times Desperate Measures (ver 2 by bloodlustx36).gp5", + "Underoath - Desperate Times Desperate Measures.gp5" + ] + }, + { + "work": "underoath - down set go", + "files": [ + "Underoath - Down Set Go (ver 2 by LookIntotheAir).gp5", + "Underoath - Down Set Go.gp5" + ] + }, + { + "work": "underoath - everyone looks so good from here", + "files": [ + "Underoath - Everyone Looks So Good From Here (ver 2 by seanwatson18).gp5", + "Underoath - Everyone Looks So Good From Here.gp4" + ] + }, + { + "work": "underoath - im content with losing", + "files": [ + "Underoath - Im Content With Losing (ver 2 by kikiu).gp5", + "Underoath - Im Content With Losing.gp4" + ] + }, + { + "work": "underoath - its dangerous business walking out your front door", + "files": [ + "Underoath - Its Dangerous Business Walking Out Your Front Door.gp4", + "Underoath - Its Dangerous Business Walking Out Your Front Door.gp5" + ] + }, + { + "work": "underoath - ive got ten friends and a crowbar that says you aint gonna do jack", + "files": [ + "Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack (ver 2 by LookIntotheAir).gp5", + "Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4" + ] + }, + { + "work": "underoath - last", + "files": [ + "Underoath - Last (ver 2 by catalan123).gp5", + "Underoath - Last.gp5" + ] + }, + { + "work": "underoath - never meant to break your heart", + "files": [ + "Underoath - Never Meant To Break Your Heart (ver 2 by @xel).gp5", + "Underoath - Never Meant To Break Your Heart.gp4" + ] + }, + { + "work": "underoath - to whom it may concern", + "files": [ + "Underoath - To Whom It May Concern (ver 2 by n.schulz29).gpx", + "Underoath - To Whom It May Concern.gp5" + ] + }, + { + "work": "underoath - too bright to see too loud to hear", + "files": [ + "Underoath - Too Bright To See Too Loud To Hear (ver 2 by jayman5671).gp5", + "Underoath - Too Bright To See Too Loud To Hear.gp5" + ] + }, + { + "work": "underoath - young and aspiring", + "files": [ + "Underoath - Young And Aspiring (ver 2 by _Doggy_).gp5", + "Underoath - Young And Aspiring.gp4" + ] + }, + { + "work": "underoath - youre ever so inviting", + "files": [ + "Underoath - Youre Ever So Inviting (ver 2 by josh-josh-josh).gpx", + "Underoath - Youre Ever So Inviting.gp5" + ] + } + ] + }, + "annotation_coverage": { + "structure": 9907, + "gesture": 9907, + "complexity": 9907, + "rights": 9907, + "style_cohort": 9907, + "duplicate": 2537, + "ensemble": 9717, + "total_chunks": 9907 + }, + "ensemble_integrity": { + "manifest_groups": 405, + "group_member_ids": 9717, + "chunks_with_ensemble_ref": 9717, + "broken_member_refs": [], + "orphan_ensemble_refs": [] + }, + "duplicates": { + "content_duplicate_tabs": [ + [ + "tabs/Underoath - I Got 10 Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4", + "tabs/Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4" + ] + ] + }, + "format_distribution": { + "gp": 2105, + "gp3": 18, + "gp4": 748, + "gp5": 5632, + "gpx": 1404 + } +} diff --git a/census/src/main.rs b/census/src/main.rs new file mode 100644 index 0000000..77a36e5 --- /dev/null +++ b/census/src/main.rs @@ -0,0 +1,909 @@ +//! Real-corpus census — a read-only harness that reconciles the corpus records +//! against the source tabs they cite and reports migration-readiness (v8/v9/v10 +//! coverage), annotation coverage, ensemble integrity, duplicates, and the +//! multi-transcription "work" candidates a `song_id` (ADR-0031) must group. +//! +//! The population is the **individual `*.chunk.json` files** (what the loader +//! globs), parsed with the production `ChunkMeta` — not a single manifest, since +//! the real corpus carries several (a small curated top-level set and a large +//! ingest set). Every `manifest.json` is loaded too, for schema version, group +//! definitions, and manifest↔file reconciliation. Tabs are hashed with the +//! production `source_sha256`, so the numbers match the future v9 backfill by +//! construction. Changes no corpus data; a directory it cannot read is a hard +//! error (never a silent partial report). +//! +//! Usage (from the repo root — `census` is excluded from the workspace, so use +//! `--manifest-path`, not `-p`): +//! cargo run --manifest-path census/Cargo.toml -- [out_json] [out_md] + +#![allow(clippy::too_many_lines, clippy::cast_precision_loss)] + +use std::collections::{BTreeMap, BTreeSet}; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::ExitCode; + +use serde::Serialize; + +use griff_core::corpus::{source_sha256, ChunkMeta, CorpusManifest, EnsembleGroup, SourceFormat}; + +fn main() -> ExitCode { + let args: Vec = std::env::args().collect(); + let (Some(corpus_dir), Some(tabs_dir)) = (args.get(1), args.get(2)) else { + eprintln!("usage: census [out_json] [out_md]"); + return ExitCode::FAILURE; + }; + let out_json = args + .get(3) + .cloned() + .unwrap_or_else(|| "census/corpus-health.json".to_owned()); + let out_md = args + .get(4) + .cloned() + .unwrap_or_else(|| "docs/audit/2026-07-real-corpus-health.md".to_owned()); + + let health = match census(Path::new(corpus_dir), Path::new(tabs_dir)) { + Ok(h) => h, + Err(e) => { + eprintln!("census failed: {e}"); + return ExitCode::FAILURE; + } + }; + + let json = serde_json::to_string_pretty(&health).expect("serialize"); + if let Err(e) = fs::write(&out_json, format!("{json}\n")) { + eprintln!("write {out_json}: {e}"); + return ExitCode::FAILURE; + } + if let Err(e) = fs::write(&out_md, render_markdown(&health)) { + eprintln!("write {out_md}: {e}"); + return ExitCode::FAILURE; + } + eprintln!("wrote {out_json} and {out_md}"); + ExitCode::SUCCESS +} + +// ── report shape ────────────────────────────────────────────────────────────── + +#[derive(Serialize)] +struct Health { + /// Ties the report to an exact input set: SHA-256 over the sorted, + /// domain-tagged `::` lines for every chunk file, + /// manifest, and tab. Any content change, rename, or path swap changes it; + /// traversal order does not. Deterministic re-runs on the same inputs match. + input_digest: String, + manifests: Vec, + counts: Counts, + manifest_reconciliation: ManifestReconciliation, + source_reconciliation: SourceReconciliation, + v9_coverage: V9Coverage, + v10_readiness: V10Readiness, + annotation_coverage: AnnotationCoverage, + ensemble_integrity: EnsembleIntegrity, + duplicates: Duplicates, + format_distribution: BTreeMap, +} + +#[derive(Serialize)] +struct ManifestSummary { + path: String, + schema_version: u32, + chunks: usize, + groups: usize, +} + +#[derive(Serialize)] +struct Counts { + chunk_files: usize, + chunk_parse_errors: usize, + manifest_chunk_records: usize, + unique_referenced_filenames: usize, + tab_files: usize, +} + +#[derive(Serialize)] +struct ManifestReconciliation { + files_covered_by_a_manifest: usize, + files_not_in_any_manifest: usize, + manifest_ids_without_a_file: usize, +} + +#[derive(Serialize)] +struct SourceReconciliation { + matched_sources: usize, + /// Every unique source filename the chunks reference (the full list). + referenced_sources: Vec, + missing_sources: Vec, + ambiguous_sources: Vec, + /// Relative paths of tab files no chunk references (physical files, so tabs + /// with a shared basename in different directories are listed separately). + unreferenced_tabs: Vec, +} + +#[derive(Serialize)] +struct V9Coverage { + sha256_present: usize, + track_index_present: usize, + total_chunks: usize, +} + +#[derive(Serialize)] +struct V10Readiness { + song_id_field_in_schema: bool, + distinct_works_estimated: usize, + multi_transcription_works: Vec, +} + +#[derive(Serialize)] +struct WorkGroup { + work: String, + files: Vec, +} + +#[derive(Serialize)] +struct AnnotationCoverage { + structure: usize, + gesture: usize, + complexity: usize, + rights: usize, + style_cohort: usize, + duplicate: usize, + ensemble: usize, + total_chunks: usize, +} + +#[derive(Serialize)] +struct EnsembleIntegrity { + manifest_groups: usize, + group_member_ids: usize, + chunks_with_ensemble_ref: usize, + broken_member_refs: Vec, + orphan_ensemble_refs: Vec, +} + +#[derive(Serialize)] +struct Duplicates { + content_duplicate_tabs: Vec>, +} + +// ── census ──────────────────────────────────────────────────────────────────── + +fn census(corpus_dir: &Path, tabs_dir: &Path) -> Result { + // 1. Population: every individual *.chunk.json, parsed with the production type. + let mut chunks: Vec = Vec::new(); + let mut parse_errors = 0usize; + // Every input the report depends on, domain-tagged with its relative path and + // content hash, so the digest binds the *whole* set (chunks, manifests, tabs) + // — a manifest edit, a tab rename, or a path swap all change it. + let mut inputs: Vec = Vec::new(); + let mut chunk_files = 0usize; + for path in walk(corpus_dir)? { + if !path.to_string_lossy().ends_with(".chunk.json") { + continue; + } + chunk_files += 1; + let bytes = fs::read(&path).map_err(|e| format!("read {}: {e}", path.display()))?; + inputs.push(format!( + "chunk:{}:{}", + rel(corpus_dir, &path), + source_sha256(&bytes) + )); + match serde_json::from_slice::(&bytes) { + Ok(c) => chunks.push(c), + Err(_) => parse_errors += 1, + } + } + + // 2. Manifests: schema version, group defs, and the ids they enumerate. + let mut manifests: Vec = Vec::new(); + let mut groups: Vec = Vec::new(); + let mut manifest_ids: BTreeSet = BTreeSet::new(); + let mut manifest_chunk_records = 0usize; + for path in walk(corpus_dir)? { + if path.file_name().and_then(|n| n.to_str()) != Some("manifest.json") { + continue; + } + let bytes = fs::read(&path).map_err(|e| format!("read {}: {e}", path.display()))?; + inputs.push(format!( + "manifest:{}:{}", + rel(corpus_dir, &path), + source_sha256(&bytes) + )); + let m: CorpusManifest = + serde_json::from_slice(&bytes).map_err(|e| format!("parse {}: {e}", path.display()))?; + manifest_chunk_records += m.chunks.len(); + for c in &m.chunks { + manifest_ids.insert(c.id.0.clone()); + } + manifests.push(ManifestSummary { + path: rel(corpus_dir, &path), + schema_version: m.schema_version, + chunks: m.chunks.len(), + groups: m.groups.len(), + }); + groups.extend(m.groups); + } + manifests.sort_by(|a, b| a.path.cmp(&b.path)); + + // 3. Tabs: keep every physical file (relative path), indexed by basename/stem + // for lookup and by content hash for duplicate detection. + let mut by_basename: BTreeMap> = BTreeMap::new(); + let mut by_stem: BTreeMap> = BTreeMap::new(); + let mut hash_to_paths: BTreeMap> = BTreeMap::new(); + let mut tab_paths: Vec = Vec::new(); + for path in walk(tabs_dir)? { + if !is_tab(&path) { + continue; + } + let relpath = rel(tabs_dir, &path); + tab_paths.push(relpath.clone()); + let name = basename(&path); + by_basename + .entry(name.clone()) + .or_default() + .push(relpath.clone()); + by_stem + .entry(stem(&name)) + .or_default() + .push(relpath.clone()); + let bytes = fs::read(&path).map_err(|e| format!("read {}: {e}", path.display()))?; + let sha = source_sha256(&bytes); + inputs.push(format!("tab:{relpath}:{sha}")); + hash_to_paths.entry(sha).or_default().insert(relpath); + } + let tab_files = tab_paths.len(); + let input_digest = input_digest_of(inputs); + + // 4. Walk the population. + let total = chunks.len(); + let mut referenced: BTreeSet = BTreeSet::new(); + let (mut sha_present, mut track_present) = (0usize, 0usize); + let mut ann = [0usize; 7]; + let mut fmt: BTreeMap = BTreeMap::new(); + let mut chunk_ids: BTreeSet = BTreeSet::new(); + let mut ensemble_ref_groups: BTreeSet = BTreeSet::new(); + let mut chunks_with_ensemble = 0usize; + for c in &chunks { + chunk_ids.insert(c.id.0.clone()); + referenced.insert(c.source.filename.clone()); + sha_present += usize::from(c.source.sha256.is_some()); + track_present += usize::from(c.source.track_index.is_some()); + ann[0] += usize::from(c.structure.is_some()); + ann[1] += usize::from(c.gesture.is_some()); + ann[2] += usize::from(c.complexity.is_some()); + ann[3] += usize::from(c.rights.is_some()); + ann[4] += usize::from(c.style_cohort.is_some()); + ann[5] += usize::from(c.duplicate.is_some()); + if let Some(e) = &c.ensemble { + ann[6] += 1; + chunks_with_ensemble += 1; + ensemble_ref_groups.insert(e.group_id.clone()); + } + *fmt.entry(format_name(c.source.format)).or_default() += 1; + } + + // 5. Manifest ↔ file reconciliation. + let files_covered = chunk_ids + .iter() + .filter(|id| manifest_ids.contains(*id)) + .count(); + let files_uncovered = chunk_ids.len() - files_covered; + let manifest_orphans = manifest_ids + .iter() + .filter(|id| !chunk_ids.contains(*id)) + .count(); + + // 6. Source ↔ tab reconciliation (over physical tab paths). + let (mut matched, mut missing, mut ambiguous) = (0usize, Vec::new(), Vec::new()); + let mut referenced_paths: BTreeSet = BTreeSet::new(); + for f in &referenced { + match resolve(f, &by_basename, &by_stem) { + Resolution::Unique(p) => { + matched += 1; + referenced_paths.insert(p); + } + Resolution::Missing => missing.push(f.clone()), + Resolution::Ambiguous(paths) => { + ambiguous.push(f.clone()); + referenced_paths.extend(paths); + } + } + } + // Physical partition: every tab file is matched/ambiguous (in referenced_paths) + // or unreferenced — a set difference over concrete paths, not a name heuristic. + let mut unreferenced_tabs: Vec = tab_paths + .iter() + .filter(|p| !referenced_paths.contains(*p)) + .cloned() + .collect(); + unreferenced_tabs.sort(); + unreferenced_tabs.dedup(); + missing.sort(); + ambiguous.sort(); + debug_assert_eq!( + referenced_paths.len() + unreferenced_tabs.len(), + tab_paths.iter().collect::>().len(), + "physical tabs must partition into referenced ∪ unreferenced" + ); + + // 7. Works — normalized composition key (strips the `(ver N by X)` suffix). + let mut works: BTreeMap> = BTreeMap::new(); + for f in &referenced { + works.entry(work_key(f)).or_default().insert(f.clone()); + } + let mut multi: Vec = works + .iter() + .filter(|(_, files)| files.len() > 1) + .map(|(w, files)| WorkGroup { + work: w.clone(), + files: files.iter().cloned().collect(), + }) + .collect(); + multi.sort_by(|a, b| b.files.len().cmp(&a.files.len()).then(a.work.cmp(&b.work))); + + // 8. Ensemble integrity (union of all manifests' groups vs the population). + let mut group_ids: BTreeSet = BTreeSet::new(); + let mut group_member_ids = 0usize; + let mut broken = Vec::new(); + for g in &groups { + group_ids.insert(g.id.clone()); + for m in &g.members { + group_member_ids += 1; + if !chunk_ids.contains(&m.0) { + broken.push(format!("group {} -> missing chunk {}", g.id, m.0)); + } + } + } + let mut orphan: Vec = ensemble_ref_groups + .iter() + .filter(|g| !group_ids.contains(*g)) + .cloned() + .collect(); + orphan.sort(); + broken.sort(); + broken.truncate(50); + + // 9. Content-duplicate tabs. + let mut content_dupes: Vec> = hash_to_paths + .values() + .filter(|paths| paths.len() > 1) + .map(|paths| paths.iter().cloned().collect()) + .collect(); + content_dupes.sort(); + + Ok(Health { + input_digest, + manifests, + counts: Counts { + chunk_files, + chunk_parse_errors: parse_errors, + manifest_chunk_records, + unique_referenced_filenames: referenced.len(), + tab_files, + }, + manifest_reconciliation: ManifestReconciliation { + files_covered_by_a_manifest: files_covered, + files_not_in_any_manifest: files_uncovered, + manifest_ids_without_a_file: manifest_orphans, + }, + source_reconciliation: SourceReconciliation { + matched_sources: matched, + referenced_sources: referenced.iter().cloned().collect(), + missing_sources: missing, + ambiguous_sources: ambiguous, + unreferenced_tabs, + }, + v9_coverage: V9Coverage { + sha256_present: sha_present, + track_index_present: track_present, + total_chunks: total, + }, + v10_readiness: V10Readiness { + song_id_field_in_schema: false, + distinct_works_estimated: works.len(), + multi_transcription_works: multi, + }, + annotation_coverage: AnnotationCoverage { + structure: ann[0], + gesture: ann[1], + complexity: ann[2], + rights: ann[3], + style_cohort: ann[4], + duplicate: ann[5], + ensemble: ann[6], + total_chunks: total, + }, + ensemble_integrity: EnsembleIntegrity { + manifest_groups: groups.len(), + group_member_ids, + chunks_with_ensemble_ref: chunks_with_ensemble, + broken_member_refs: broken, + orphan_ensemble_refs: orphan, + }, + duplicates: Duplicates { + content_duplicate_tabs: content_dupes, + }, + format_distribution: fmt, + }) +} + +// ── helpers ─────────────────────────────────────────────────────────────────── + +/// All files under `dir`, recursively, sorted. A directory that cannot be read +/// is a hard error, so the census never silently reports over a partial corpus. +fn walk(dir: &Path) -> Result, String> { + let mut out = Vec::new(); + let entries = fs::read_dir(dir).map_err(|e| format!("read_dir {}: {e}", dir.display()))?; + for entry in entries { + let path = entry + .map_err(|e| format!("dir entry in {}: {e}", dir.display()))? + .path(); + if path.is_dir() { + out.extend(walk(&path)?); + } else { + out.push(path); + } + } + out.sort(); + Ok(out) +} + +fn rel(base: &Path, p: &Path) -> String { + p.strip_prefix(base) + .unwrap_or(p) + .to_string_lossy() + .into_owned() +} + +fn is_tab(p: &Path) -> bool { + matches!( + p.extension().and_then(|e| e.to_str()), + Some("gp" | "gp3" | "gp4" | "gp5" | "gpx" | "mid" | "midi") + ) +} + +fn basename(p: &Path) -> String { + p.file_name() + .map(|n| n.to_string_lossy().into_owned()) + .unwrap_or_default() +} + +fn stem(name: &str) -> String { + name.rsplit_once('.') + .map_or_else(|| name.to_owned(), |(s, _)| s.to_owned()) +} + +/// How a referenced source filename resolves against the physical tabs — the +/// concrete path(s), not just a count, so the caller can partition the tabs. +#[derive(Debug, PartialEq, Eq)] +enum Resolution { + Unique(String), + Missing, + Ambiguous(Vec), +} + +/// Resolve `name` to physical tab path(s): exact basename first, else stem. +fn resolve( + name: &str, + by_basename: &BTreeMap>, + by_stem: &BTreeMap>, +) -> Resolution { + let paths = by_basename.get(name).or_else(|| by_stem.get(&stem(name))); + match paths { + None => Resolution::Missing, + Some(v) if v.is_empty() => Resolution::Missing, + Some(v) if v.len() == 1 => Resolution::Unique(v[0].clone()), + Some(v) => Resolution::Ambiguous(v.clone()), + } +} + +/// SHA-256 over the sorted domain-tagged input lines. Sorting makes it +/// order-independent; every distinct input line changes it. +fn input_digest_of(mut inputs: Vec) -> String { + inputs.sort(); + inputs.dedup(); + source_sha256(inputs.join("\n").as_bytes()) +} + +/// Strip a trailing parenthesized transcriber/version suffix — the real corpus +/// naming is `Artist - Title (ver N by transcriber).ext`. Only a paren group +/// that starts with `ver`, contains ` by `, or is all digits is stripped, so a +/// title that legitimately ends in parentheses (e.g. `(Reprise)`) is preserved. +fn strip_version_suffix(s: &str) -> &str { + let trimmed = s.trim_end(); + if !trimmed.ends_with(')') { + return s; + } + let Some(open) = trimmed.rfind('(') else { + return s; + }; + let inner = trimmed[open + 1..trimmed.len() - 1].trim(); + let lower = inner.to_lowercase(); + let is_version = lower.starts_with("ver") + || lower.contains(" by ") + || (!inner.is_empty() && inner.chars().all(|c| c.is_ascii_digit())); + if is_version { + trimmed[..open].trim_end() + } else { + s + } +} + +/// Normalize a source filename to a composition (Work) key: drop the extension +/// and the `(ver N by X)` suffix, lowercase, collapse whitespace. +fn work_key(filename: &str) -> String { + let base = strip_version_suffix(&stem(filename)).to_lowercase(); + base.split_whitespace().collect::>().join(" ") +} + +fn format_name(f: SourceFormat) -> String { + match f { + SourceFormat::Midi => "midi", + SourceFormat::Gp3 => "gp3", + SourceFormat::Gp4 => "gp4", + SourceFormat::Gp5 => "gp5", + SourceFormat::Gpx => "gpx", + SourceFormat::Gp => "gp", + } + .to_owned() +} + +// ── markdown (rendered from the same struct — one source of truth) ──────────── + +fn pct(n: usize, total: usize) -> String { + if total == 0 { + "n/a".to_owned() + } else { + format!("{:.1}%", 100.0 * n as f64 / total as f64) + } +} + +fn render_markdown(h: &Health) -> String { + let total = h.counts.chunk_files; + let a = &h.annotation_coverage; + let sr = &h.source_reconciliation; + let mut s = String::new(); + s.push_str("# 2026-07 — Real corpus health census\n\n"); + s.push_str( + "Read-only census of the actual corpus, generated by the isolated \ + `census/` tool (`cargo run --manifest-path census/Cargo.toml -- \ + `). Rendered from `corpus-health.json`; \ + re-running on the same files reproduces both. Changes no corpus data. \ + First artifact to ground the contract series (benchmark, reachability \ + lab, ADR-0031 song identity) against the real corpus rather than \ + synthetic data.\n\n", + ); + s.push_str(&format!( + "Input digest (SHA-256 over sorted `::` lines for \ + every chunk, manifest, and tab): `{}`\n\n", + h.input_digest + )); + + s.push_str("## Layers of the corpus\n\n"); + s.push_str(&format!( + "The population is the **{} individual `*.chunk.json` files** (what the \ + loader globs); {} failed to parse. Separately, {} `manifest.json` file(s) \ + enumerate their own subsets:\n\n", + h.counts.chunk_files, + h.counts.chunk_parse_errors, + h.manifests.len() + )); + s.push_str("| Manifest | schema | chunks | groups |\n| --- | --- | --- | --- |\n"); + for m in &h.manifests { + s.push_str(&format!( + "| `{}` | {} | {} | {} |\n", + m.path, m.schema_version, m.chunks, m.groups + )); + } + let mr = &h.manifest_reconciliation; + s.push_str(&format!( + "\nManifest ↔ file reconciliation: **{}** files covered by a manifest, \ + **{}** files in no manifest, **{}** manifest ids with no file.\n\n", + mr.files_covered_by_a_manifest, + mr.files_not_in_any_manifest, + mr.manifest_ids_without_a_file + )); + + s.push_str("## Counts\n\n| Fact | Value |\n| --- | --- |\n"); + s.push_str(&format!( + "| chunk files (population) | **{}** |\n", + h.counts.chunk_files + )); + s.push_str(&format!( + "| chunk parse errors | {} |\n", + h.counts.chunk_parse_errors + )); + s.push_str(&format!( + "| manifest chunk records (all manifests) | {} |\n", + h.counts.manifest_chunk_records + )); + s.push_str(&format!( + "| unique referenced source filenames | {} |\n", + h.counts.unique_referenced_filenames + )); + s.push_str(&format!( + "| tab files under `tabs/` | {} |\n\n", + h.counts.tab_files + )); + + s.push_str("## Source ↔ tab reconciliation\n\n| Outcome | Count |\n| --- | --- |\n"); + s.push_str(&format!("| matched sources | {} |\n", sr.matched_sources)); + s.push_str(&format!( + "| missing (referenced, no tab) | {} |\n", + sr.missing_sources.len() + )); + s.push_str(&format!( + "| ambiguous (referenced → >1 tab) | {} |\n", + sr.ambiguous_sources.len() + )); + s.push_str(&format!( + "| unreferenced tabs | {} |\n\n", + sr.unreferenced_tabs.len() + )); + list_section(&mut s, "Referenced sources", &sr.referenced_sources, 60); + list_section(&mut s, "Missing sources", &sr.missing_sources, 40); + list_section(&mut s, "Ambiguous sources", &sr.ambiguous_sources, 40); + list_section(&mut s, "Unreferenced tabs", &sr.unreferenced_tabs, 60); + + s.push_str("## Migration readiness\n\n"); + s.push_str( + "**v9 (source-file identity).**\n\n| Field | Present | Coverage |\n| --- | --- | --- |\n", + ); + s.push_str(&format!( + "| `sha256` | {} | {} |\n| `track_index` | {} | {} |\n\n", + h.v9_coverage.sha256_present, + pct(h.v9_coverage.sha256_present, total), + h.v9_coverage.track_index_present, + pct(h.v9_coverage.track_index_present, total), + )); + s.push_str(&format!( + "**v10 (song identity).** `song_id` field in schema: **{}**. Estimated \ + distinct compositions (Work candidates): **{}**. Multi-transcription works \ + (the leakage ADR-0031 closes): **{}** (covering {} source files).\n\n", + h.v10_readiness.song_id_field_in_schema, + h.v10_readiness.distinct_works_estimated, + h.v10_readiness.multi_transcription_works.len(), + h.v10_readiness + .multi_transcription_works + .iter() + .map(|w| w.files.len()) + .sum::(), + )); + if !h.v10_readiness.multi_transcription_works.is_empty() { + s.push_str("
Multi-transcription works\n\n"); + s.push_str("| Work (normalized) | Source files |\n| --- | --- |\n"); + for w in &h.v10_readiness.multi_transcription_works { + s.push_str(&format!("| `{}` | {} |\n", w.work, w.files.join("
"))); + } + s.push_str("\n
\n\n"); + } + + s.push_str("## Annotation coverage\n\n| Field | Present | Coverage |\n| --- | --- | --- |\n"); + for (name, n) in [ + ("structure", a.structure), + ("gesture", a.gesture), + ("complexity", a.complexity), + ("rights", a.rights), + ("style_cohort", a.style_cohort), + ("duplicate", a.duplicate), + ("ensemble", a.ensemble), + ] { + s.push_str(&format!("| `{name}` | {n} | {} |\n", pct(n, total))); + } + s.push('\n'); + + s.push_str("## Ensemble integrity\n\n| Fact | Value |\n| --- | --- |\n"); + let e = &h.ensemble_integrity; + s.push_str(&format!( + "| groups (all manifests) | {} |\n", + e.manifest_groups + )); + s.push_str(&format!("| group member ids | {} |\n", e.group_member_ids)); + s.push_str(&format!( + "| chunks with ensemble ref | {} |\n", + e.chunks_with_ensemble_ref + )); + s.push_str(&format!( + "| broken member refs | {} |\n", + e.broken_member_refs.len() + )); + s.push_str(&format!( + "| orphan ensemble refs | {} |\n\n", + e.orphan_ensemble_refs.len() + )); + list_section(&mut s, "Broken member refs", &e.broken_member_refs, 40); + list_section(&mut s, "Orphan ensemble refs", &e.orphan_ensemble_refs, 40); + + s.push_str("## Duplicates & formats\n\n"); + s.push_str(&format!( + "Content-duplicate tab groups (identical bytes, different paths): **{}**.\n\n", + h.duplicates.content_duplicate_tabs.len() + )); + for g in &h.duplicates.content_duplicate_tabs { + s.push_str(&format!("- {}\n", g.join(" == "))); + } + if !h.duplicates.content_duplicate_tabs.is_empty() { + s.push('\n'); + } + s.push_str("Source format distribution (chunks):\n\n| Format | Chunks |\n| --- | --- |\n"); + for (k, v) in &h.format_distribution { + s.push_str(&format!("| {k} | {v} |\n")); + } + s.push('\n'); + + s.push_str( + "## Reading\n\nThe corpus is fully **measured** (structure / gesture / \ + complexity / rights) but sits at the **weakest source-identity level**: \ + every manifest is schema v8, so `sha256` and `track_index` are absent \ + everywhere. The fail-closed holdout contracts (Phase-0 audit; ADR-0031) \ + therefore currently block on the whole corpus — the immediate \ + prerequisite is the **v9 `sha256` backfill**, then **v10 `song_id`** \ + curation. The multi-transcription works above are the concrete leakage \ + ADR-0031 addresses. The two-manifest split (a small curated set and a \ + large ingest set) is the real shape the migration must handle.\n", + ); + s +} + +fn list_section(s: &mut String, title: &str, items: &[String], cap: usize) { + if items.is_empty() { + return; + } + s.push_str(&format!( + "
{title} ({})\n\n", + items.len() + )); + for it in items.iter().take(cap) { + s.push_str(&format!("- `{it}`\n")); + } + if items.len() > cap { + s.push_str(&format!( + "- … and {} more (see `corpus-health.json`)\n", + items.len() - cap + )); + } + s.push_str("\n
\n\n"); +} + +// ── tests ───────────────────────────────────────────────────────────────────── + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn stem_drops_the_last_extension() { + assert_eq!(stem("Song.gp5"), "Song"); + assert_eq!(stem("A - B (ver 2).gpx"), "A - B (ver 2)"); + assert_eq!(stem("noext"), "noext"); + } + + #[test] + fn version_suffix_is_stripped_only_when_it_is_a_version() { + assert_eq!(strip_version_suffix("A - B (ver 2 by X)"), "A - B"); + assert_eq!(strip_version_suffix("A - B (ver by X)"), "A - B"); + assert_eq!(strip_version_suffix("A - B (2)"), "A - B"); + // Not a version marker — preserved. + assert_eq!(strip_version_suffix("Song (Reprise)"), "Song (Reprise)"); + assert_eq!(strip_version_suffix("Plain Title"), "Plain Title"); + } + + #[test] + fn work_key_groups_transcriptions_of_one_composition() { + let a = work_key("A Lot Like Birds - Connector.gp5"); + let b = work_key("A Lot Like Birds - Connector (ver 2 by LPFzCS_LMS).gp5"); + let c = work_key("A Lot Like Birds - Connector (ver 3 by someone).gpx"); + assert_eq!(a, "a lot like birds - connector"); + assert_eq!(a, b, "base and (ver 2 …) must share a work key"); + assert_eq!(b, c, "different transcriber versions must share a work key"); + // A different song must not collapse into the same work. + assert_ne!(a, work_key("A Lot Like Birds - Divisi.gp5")); + } + + #[test] + fn resolve_returns_concrete_paths_exact_then_stem() { + let mut by_basename: BTreeMap> = BTreeMap::new(); + by_basename.insert("x.gp5".to_owned(), vec!["a/x.gp5".to_owned()]); + let mut by_stem: BTreeMap> = BTreeMap::new(); + by_stem.insert( + "y".to_owned(), + vec!["a/y.gpx".to_owned(), "b/y.gp5".to_owned()], + ); + assert_eq!( + resolve("x.gp5", &by_basename, &by_stem), + Resolution::Unique("a/x.gp5".to_owned()) + ); + assert_eq!( + resolve("y.gp5", &by_basename, &by_stem), + Resolution::Ambiguous(vec!["a/y.gpx".to_owned(), "b/y.gp5".to_owned()]) + ); + assert_eq!( + resolve("missing.gp5", &by_basename, &by_stem), + Resolution::Missing + ); + } + + #[test] + fn tabs_partition_referenced_and_unreferenced_by_path() { + // The regression the arbiter named: referenced song.gp5, tabs {song.gp5, + // song.gpx} — exact resolution picks .gp5; .gpx is unreferenced (a + // name/stem heuristic would wrongly mark both referenced). + let mut by_basename: BTreeMap> = BTreeMap::new(); + by_basename.insert("song.gp5".to_owned(), vec!["song.gp5".to_owned()]); + by_basename.insert("song.gpx".to_owned(), vec!["song.gpx".to_owned()]); + let mut by_stem: BTreeMap> = BTreeMap::new(); + by_stem.insert( + "song".to_owned(), + vec!["song.gp5".to_owned(), "song.gpx".to_owned()], + ); + let tabs = ["song.gp5".to_owned(), "song.gpx".to_owned()]; + + let mut referenced_paths: BTreeSet = BTreeSet::new(); + match resolve("song.gp5", &by_basename, &by_stem) { + Resolution::Unique(p) => { + referenced_paths.insert(p); + } + other => panic!("expected Unique, got {other:?}"), + } + let unreferenced: Vec<&String> = tabs + .iter() + .filter(|p| !referenced_paths.contains(*p)) + .collect(); + assert_eq!( + referenced_paths.iter().collect::>(), + vec!["song.gp5"] + ); + assert_eq!(unreferenced, vec!["song.gpx"]); + assert_eq!(referenced_paths.len() + unreferenced.len(), tabs.len()); // partition + } + + #[test] + fn input_digest_is_order_independent_and_change_sensitive() { + let a = input_digest_of(vec![ + "chunk:a.chunk.json:11".to_owned(), + "manifest:manifest.json:22".to_owned(), + "tab:x.gp5:33".to_owned(), + ]); + // Permuted order → same digest. + let b = input_digest_of(vec![ + "tab:x.gp5:33".to_owned(), + "chunk:a.chunk.json:11".to_owned(), + "manifest:manifest.json:22".to_owned(), + ]); + assert_eq!(a, b, "sorting makes the digest order-independent"); + // A manifest content change (different sha) → different digest. + let manifest_changed = input_digest_of(vec![ + "chunk:a.chunk.json:11".to_owned(), + "manifest:manifest.json:99".to_owned(), + "tab:x.gp5:33".to_owned(), + ]); + assert_ne!( + a, manifest_changed, + "a manifest change must change the digest" + ); + // A tab rename (same sha, different path) → different digest. + let tab_renamed = input_digest_of(vec![ + "chunk:a.chunk.json:11".to_owned(), + "manifest:manifest.json:22".to_owned(), + "tab:y.gp5:33".to_owned(), + ]); + assert_ne!(a, tab_renamed, "a tab rename must change the digest"); + // Adding a tab → different digest. + let mut plus = vec![ + "chunk:a.chunk.json:11".to_owned(), + "manifest:manifest.json:22".to_owned(), + "tab:x.gp5:33".to_owned(), + ]; + plus.push("tab:z.gp5:44".to_owned()); + assert_ne!( + a, + input_digest_of(plus), + "adding a tab must change the digest" + ); + } + + #[test] + fn walk_errors_on_a_missing_directory() { + assert!(walk(Path::new("definitely/not/a/real/dir/xyzzy")).is_err()); + } +} diff --git a/docs/audit/2026-07-real-corpus-health.md b/docs/audit/2026-07-real-corpus-health.md new file mode 100644 index 0000000..3d7d897 --- /dev/null +++ b/docs/audit/2026-07-real-corpus-health.md @@ -0,0 +1,270 @@ +# 2026-07 — Real corpus health census + +Read-only census of the actual corpus, generated by the isolated `census/` tool (`cargo run --manifest-path census/Cargo.toml -- `). Rendered from `corpus-health.json`; re-running on the same files reproduces both. Changes no corpus data. First artifact to ground the contract series (benchmark, reachability lab, ADR-0031 song identity) against the real corpus rather than synthetic data. + +Input digest (SHA-256 over sorted `::` lines for every chunk, manifest, and tab): `6955b33bdfa27e712ae64b12be8b3b0b4c509a496377c523331ea769e73e9c4e` + +## Layers of the corpus + +The population is the **9907 individual `*.chunk.json` files** (what the loader globs); 0 failed to parse. Separately, 2 `manifest.json` file(s) enumerate their own subsets: + +| Manifest | schema | chunks | groups | +| --- | --- | --- | --- | +| `ingest/manifest.json` | 8 | 9687 | 400 | +| `manifest.json` | 8 | 220 | 5 | + +Manifest ↔ file reconciliation: **9907** files covered by a manifest, **0** files in no manifest, **0** manifest ids with no file. + +## Counts + +| Fact | Value | +| --- | --- | +| chunk files (population) | **9907** | +| chunk parse errors | 0 | +| manifest chunk records (all manifests) | 9907 | +| unique referenced source filenames | 400 | +| tab files under `tabs/` | 410 | + +## Source ↔ tab reconciliation + +| Outcome | Count | +| --- | --- | +| matched sources | 400 | +| missing (referenced, no tab) | 0 | +| ambiguous (referenced → >1 tab) | 0 | +| unreferenced tabs | 10 | + +
Referenced sources (400) + +- `A Lot Like Birds - A Satire Of A Satire Is Tiring.gpx` +- `A Lot Like Birds - Always Burning Always Dark.gp5` +- `A Lot Like Birds - Connector (ver 2 by LPFzCS_LMS).gp5` +- `A Lot Like Birds - Connector.gp5` +- `A Lot Like Birds - Divisi.gp5` +- `A Lot Like Birds - For Shelley Unheard.gp5` +- `A Lot Like Birds - From Moon To Son.gp5` +- `A Lot Like Birds - Further Below.gp5` +- `A Lot Like Birds - Good Soil Bad Seeds.gp5` +- `A Lot Like Birds - Hand Over Mouth Over And Over.gp5` +- `A Lot Like Birds - Infinite Chances.gp5` +- `A Lot Like Birds - Kuroi Ledge (ver 2 by LPFzCS_LMS).gp5` +- `A Lot Like Birds - Kuroi Ledge.gp5` +- `A Lot Like Birds - Myth Of Lasting Sympathy.gp5` +- `A Lot Like Birds - Next To Ungodliness (ver 2 by edwinal0504).gpx` +- `A Lot Like Birds - Next To Ungodliness (ver 3 by LPFzCS_LMS).gp5` +- `A Lot Like Birds - Next To Ungodliness.gp5` +- `A Lot Like Birds - No Attention For Solved Puzzles.gp5` +- `A Lot Like Birds - No Nature.gp5` +- `A Lot Like Birds - No Nurture.gp5` +- `A Lot Like Birds - Orange Time Machines Care.gpx` +- `A Lot Like Birds - Recluse.gp5` +- `A Lot Like Birds - Sesame Street Is No Place For Me.gp5` +- `A Lot Like Birds - Shaking Of The Frame.gp5` +- `A Lot Like Birds - The Smoother The Stone.gp5` +- `A Lot Like Birds - The Sound Of Us.gp5` +- `A Lot Like Birds - Think Dirty Out Loud.gpx` +- `A Lot Like Birds - Trace The Lines.gp5` +- `Dance Gavin Dance - 12 Hours 630 Miles (ver 2 by patman1416).gp5` +- `Dance Gavin Dance - 12 Hours 630 Miles.gp5` +- `Dance Gavin Dance - Alex English (ver 2 by CrashAshes43).gpx` +- `Dance Gavin Dance - Alex English (ver 3 by funkyrocker24).gp5` +- `Dance Gavin Dance - And I Told Them I Invented Times New Roman.gp5` +- `Dance Gavin Dance - Antlion.gp5` +- `Dance Gavin Dance - Attack Of The Dashing Young And Bold.gp5` +- `Dance Gavin Dance - Awkward.gp5` +- `Dance Gavin Dance - Back On Deck.gp5` +- `Dance Gavin Dance - Betrayed By The Game (ver 2 by mikoyeahyeah).gpx` +- `Dance Gavin Dance - Betrayed By The Game.gp5` +- `Dance Gavin Dance - Blood Wolf (ver 2 by Mage_Gage).gp` +- `Dance Gavin Dance - Blood Wolf.gp5` +- `Dance Gavin Dance - Bloodsucker (ver 2 by RiseAgainst34).gp` +- `Dance Gavin Dance - Bloodsucker (ver 3 by ed.garnett28).gp` +- `Dance Gavin Dance - Bloodsucker.gp5` +- `Dance Gavin Dance - Blue Dream (ver 2 by Lem0nz).gp5` +- `Dance Gavin Dance - Blue Dream.gp5` +- `Dance Gavin Dance - Born To Fail (ver 2 by president100).gp5` +- `Dance Gavin Dance - Born To Fail.gp` +- `Dance Gavin Dance - Buffalo (ver 2 by jakebohn81).gpx` +- `Dance Gavin Dance - Buffalo.gpx` +- `Dance Gavin Dance - Burning Down The Nicotine Armoire.gp5` +- `Dance Gavin Dance - Calentamiento Global.gp5` +- `Dance Gavin Dance - Care (ver 2 by president100).gp5` +- `Dance Gavin Dance - Care (ver 3 by TheLoEnd).gp` +- `Dance Gavin Dance - Care.gp` +- `Dance Gavin Dance - Carl Barker (ver 2 by rudy_rubber).gp` +- `Dance Gavin Dance - Carl Barker.gp4` +- `Dance Gavin Dance - Carve.gpx` +- `Dance Gavin Dance - Caviar (ver 2 by ed.garnett28).gp` +- `Dance Gavin Dance - Caviar.gp5` +- … and 340 more (see `corpus-health.json`) + +
+ +
Unreferenced tabs (10) + +- `tabs/A Lot Like Birds - Atoms In Evening.gp5` +- `tabs/Dance Gavin Dance - Alex English.gp5` +- `tabs/Dance Gavin Dance - Head Hunter.gp` +- `tabs/Dance Gavin Dance - One In A Million.gp` +- `tabs/Dance Gavin Dance - The Robot With Human Hair Part 4 (ver 2 by MagentaMalice).gp5` +- `tabs/Hail The Sun - Chunker.gpx` +- `tabs/Underoath - Anyone Can Dig A Hole But It Takes A Real Man To Call It Home.gpx` +- `tabs/Underoath - Reversal.gp5` +- `tabs/Wolf & Bear - Quick Sip 84.gp` +- `tabs/Wolf & Bear - Sight.gp5` + +
+ +## Migration readiness + +**v9 (source-file identity).** + +| Field | Present | Coverage | +| --- | --- | --- | +| `sha256` | 0 | 0.0% | +| `track_index` | 0 | 0.0% | + +**v10 (song identity).** `song_id` field in schema: **false**. Estimated distinct compositions (Work candidates): **257**. Multi-transcription works (the leakage ADR-0031 closes): **94** (covering 237 source files). + +
Multi-transcription works + +| Work (normalized) | Source files | +| --- | --- | +| `dance gavin dance - open your eyes and look north` | Dance Gavin Dance - Open Your Eyes And Look North (ver 2 by TalkingToAngels).gp5
Dance Gavin Dance - Open Your Eyes And Look North (ver 2).gp5
Dance Gavin Dance - Open Your Eyes And Look North (ver 3).gp5
Dance Gavin Dance - Open Your Eyes And Look North (ver 4 by oreopimp44).gp5
Dance Gavin Dance - Open Your Eyes And Look North (ver 5 by mgttg47).gp5
Dance Gavin Dance - Open Your Eyes And Look North.gp5 | +| `dance gavin dance - chucky vs the giant tortoise` | Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 2 by mikoyeahyeah).gpx
Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 3 by lacesup).gp
Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 4 by juskiwmatt).gp5
Dance Gavin Dance - Chucky Vs The Giant Tortoise (ver 5 by president100).gp5
Dance Gavin Dance - Chucky Vs The Giant Tortoise.gpx | +| `dance gavin dance - lemon meringue tie` | Dance Gavin Dance - Lemon Meringue Tie (ver 2 by kucharz89).gp5
Dance Gavin Dance - Lemon Meringue Tie (ver 3 by GonchDog).gp5
Dance Gavin Dance - Lemon Meringue Tie (ver 4 by ed.garnett28).gp
Dance Gavin Dance - Lemon Meringue Tie (ver 5 by mando2793).gpx
Dance Gavin Dance - Lemon Meringue Tie.gp5 | +| `dance gavin dance - midnight crusade` | Dance Gavin Dance - Midnight Crusade (ver 2).gp5
Dance Gavin Dance - Midnight Crusade (ver 3 by Dudealy).gpx
Dance Gavin Dance - Midnight Crusade (ver 4 by president100).gp5
Dance Gavin Dance - Midnight Crusade (ver 5 by TheLoEnd).gp
Dance Gavin Dance - Midnight Crusade.gpx | +| `underoath - in regards to myself` | Underoath - In Regards To Myself (ver 2 by re_man182).gp5
Underoath - In Regards To Myself (ver 3 by LookIntotheAir).gp5
Underoath - In Regards To Myself (ver 4 by grizzlyfs92).gp
Underoath - In Regards To Myself.gp4
Underoath - In Regards To Myself.gp5 | +| `underoath - when the sun sleeps` | Underoath - When The Sun Sleeps (ver 2 by under218).gp5
Underoath - When The Sun Sleeps (ver 3 by LookIntotheAir).gp4
Underoath - When The Sun Sleeps (ver 4 by sk8ter4life).gp5
Underoath - When The Sun Sleeps (ver 5 by js021).gp
Underoath - When The Sun Sleeps.gp4 | +| `dance gavin dance - parody catharsis` | Dance Gavin Dance - Parody Catharsis (ver 2 by lt22).gp
Dance Gavin Dance - Parody Catharsis (ver 3 by setsy).gp
Dance Gavin Dance - Parody Catharsis (ver 4 by president100).gp5
Dance Gavin Dance - Parody Catharsis.gp5 | +| `hail the sun - relax divide` | Hail The Sun - Relax Divide (ver 2 by dayamira).gp
Hail The Sun - Relax Divide (ver 3 by thursday21987).gp
Hail The Sun - Relax Divide.gp
Hail The Sun - Relax Divide.gp5 | +| `underoath - writing on the walls` | Underoath - Writing On The Walls (ver 2).gp5
Underoath - Writing On The Walls (ver 3 by re_man182).gp5
Underoath - Writing On The Walls (ver 4 by decasta).gp5
Underoath - Writing On The Walls.gp4 | +| `a lot like birds - next to ungodliness` | A Lot Like Birds - Next To Ungodliness (ver 2 by edwinal0504).gpx
A Lot Like Birds - Next To Ungodliness (ver 3 by LPFzCS_LMS).gp5
A Lot Like Birds - Next To Ungodliness.gp5 | +| `dance gavin dance - bloodsucker` | Dance Gavin Dance - Bloodsucker (ver 2 by RiseAgainst34).gp
Dance Gavin Dance - Bloodsucker (ver 3 by ed.garnett28).gp
Dance Gavin Dance - Bloodsucker.gp5 | +| `dance gavin dance - care` | Dance Gavin Dance - Care (ver 2 by president100).gp5
Dance Gavin Dance - Care (ver 3 by TheLoEnd).gp
Dance Gavin Dance - Care.gp | +| `dance gavin dance - evaporate` | Dance Gavin Dance - Evaporate (ver 2 by president100).gp5
Dance Gavin Dance - Evaporate (ver 3 by RiseAgainst34).gp
Dance Gavin Dance - Evaporate.gpx | +| `dance gavin dance - me and zoloft get along just fine` | Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 2 by kucharz89).gp5
Dance Gavin Dance - Me And Zoloft Get Along Just Fine (ver 3 by 93dric).gp5
Dance Gavin Dance - Me And Zoloft Get Along Just Fine.gp5 | +| `dance gavin dance - nasa` | Dance Gavin Dance - Nasa (ver 2 by lacesup).gpx
Dance Gavin Dance - Nasa (ver 3 by jakebohn81).gpx
Dance Gavin Dance - Nasa.gp4 | +| `dance gavin dance - prisoner` | Dance Gavin Dance - Prisoner (ver 2 by Medeses).gp
Dance Gavin Dance - Prisoner (ver 3 by president100).gp5
Dance Gavin Dance - Prisoner.gp | +| `dance gavin dance - strawberry swisher pt 2` | Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 2 by HectorDaniel).gpx
Dance Gavin Dance - Strawberry Swisher Pt 2 (ver 3 by gjikolp).gp
Dance Gavin Dance - Strawberry Swisher Pt 2.gp5 | +| `dance gavin dance - strawberry swisher pt 3` | Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 2 by marcellus97).gpx
Dance Gavin Dance - Strawberry Swisher Pt 3 (ver 3 by senorkatana11).gp
Dance Gavin Dance - Strawberry Swisher Pt 3.gpx | +| `dance gavin dance - strawberrys wake` | Dance Gavin Dance - Strawberrys Wake (ver 2 by lriax).gp5
Dance Gavin Dance - Strawberrys Wake (ver 3 by president100).gp5
Dance Gavin Dance - Strawberrys Wake.gp | +| `dance gavin dance - synergy` | Dance Gavin Dance - Synergy (ver 2 by lucascocker5).gp5
Dance Gavin Dance - Synergy (ver 3 by senorkatana11).gp
Dance Gavin Dance - Synergy.gp5 | +| `dance gavin dance - the backwards pumpkin song` | Dance Gavin Dance - The Backwards Pumpkin Song (ver 2 by TheClincher).gp5
Dance Gavin Dance - The Backwards Pumpkin Song (ver 3 by MagentaMalice).gp5
Dance Gavin Dance - The Backwards Pumpkin Song.gp5 | +| `dance gavin dance - the robot with human hair part 2` | Dance Gavin Dance - The Robot With Human Hair Part 2 (ver 2 by Thomasoman).gp5
Dance Gavin Dance - The Robot With Human Hair Part 2.gp3
Dance Gavin Dance - The Robot With Human Hair Part 2.gp5 | +| `dance gavin dance - the robot with human hair part 3` | Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 2 by tar pit trap).gp4
Dance Gavin Dance - The Robot With Human Hair Part 3 (ver 3 by m.najera.ve).gp5
Dance Gavin Dance - The Robot With Human Hair Part 3.gp5 | +| `dance gavin dance - young robot` | Dance Gavin Dance - Young Robot (ver 2 by josh-josh-josh).gpx
Dance Gavin Dance - Young Robot (ver 3 by president100).gp5
Dance Gavin Dance - Young Robot.gpx | +| `hail the sun - cosmic narcissism` | Hail The Sun - Cosmic Narcissism (ver 2 by thursday21987).gp
Hail The Sun - Cosmic Narcissism.gp
Hail The Sun - Cosmic Narcissism.gp5 | +| `underoath - a boy brushed red living in black and white` | Underoath - A Boy Brushed Red Living In Black And White (ver 2 by kiefermatot).gp4
Underoath - A Boy Brushed Red Living In Black And White (ver 3 by pnkr0cker).gp5
Underoath - A Boy Brushed Red Living In Black And White.gp4 | +| `underoath - alone in december` | Underoath - Alone In December (ver 2 by Gil310).gp5
Underoath - Alone In December (ver 3 by Lil-gzlz96).gpx
Underoath - Alone In December.gp5 | +| `underoath - casting such a thin shadow` | Underoath - Casting Such A Thin Shadow (ver 2 by bloodlustx36).gp5
Underoath - Casting Such A Thin Shadow (ver 3 by js021).gp
Underoath - Casting Such A Thin Shadow.gp5 | +| `underoath - illuminator` | Underoath - Illuminator (ver 2 by swandive).gpx
Underoath - Illuminator (ver 3 by desoulate).gp5
Underoath - Illuminator.gp5 | +| `underoath - on my teeth` | Underoath - On My Teeth (ver 2 by JackCadenhead).gpx
Underoath - On My Teeth (ver 3 by desoulate).gp5
Underoath - On My Teeth.gpx | +| `underoath - reinventing your exit` | Underoath - Reinventing Your Exit (ver 2 by alexisonfire21).gp4
Underoath - Reinventing Your Exit (ver 3 by _Doggy_).gp5
Underoath - Reinventing Your Exit.gp4 | +| `underoath - short of daybreak` | Underoath - Short Of Daybreak (ver 2 by callums_revenge).gp5
Underoath - Short Of Daybreak (ver 3 by gerald.gonzalezvazquez).gpx
Underoath - Short Of Daybreak.gp5 | +| `underoath - some will seek forgiveness others escape` | Underoath - Some Will Seek Forgiveness Others Escape (ver 2 by Jcrutch86).gp5
Underoath - Some Will Seek Forgiveness Others Escape.gp5
Underoath - Some Will Seek Forgiveness Others Escape.gpx | +| `a lot like birds - connector` | A Lot Like Birds - Connector (ver 2 by LPFzCS_LMS).gp5
A Lot Like Birds - Connector.gp5 | +| `a lot like birds - kuroi ledge` | A Lot Like Birds - Kuroi Ledge (ver 2 by LPFzCS_LMS).gp5
A Lot Like Birds - Kuroi Ledge.gp5 | +| `dance gavin dance - 12 hours 630 miles` | Dance Gavin Dance - 12 Hours 630 Miles (ver 2 by patman1416).gp5
Dance Gavin Dance - 12 Hours 630 Miles.gp5 | +| `dance gavin dance - alex english` | Dance Gavin Dance - Alex English (ver 2 by CrashAshes43).gpx
Dance Gavin Dance - Alex English (ver 3 by funkyrocker24).gp5 | +| `dance gavin dance - betrayed by the game` | Dance Gavin Dance - Betrayed By The Game (ver 2 by mikoyeahyeah).gpx
Dance Gavin Dance - Betrayed By The Game.gp5 | +| `dance gavin dance - blood wolf` | Dance Gavin Dance - Blood Wolf (ver 2 by Mage_Gage).gp
Dance Gavin Dance - Blood Wolf.gp5 | +| `dance gavin dance - blue dream` | Dance Gavin Dance - Blue Dream (ver 2 by Lem0nz).gp5
Dance Gavin Dance - Blue Dream.gp5 | +| `dance gavin dance - born to fail` | Dance Gavin Dance - Born To Fail (ver 2 by president100).gp5
Dance Gavin Dance - Born To Fail.gp | +| `dance gavin dance - buffalo` | Dance Gavin Dance - Buffalo (ver 2 by jakebohn81).gpx
Dance Gavin Dance - Buffalo.gpx | +| `dance gavin dance - carl barker` | Dance Gavin Dance - Carl Barker (ver 2 by rudy_rubber).gp
Dance Gavin Dance - Carl Barker.gp4 | +| `dance gavin dance - caviar` | Dance Gavin Dance - Caviar (ver 2 by ed.garnett28).gp
Dance Gavin Dance - Caviar.gp5 | +| `dance gavin dance - deception` | Dance Gavin Dance - Deception (ver 2 by lilgstryker).gp5
Dance Gavin Dance - Deception.gpx | +| `dance gavin dance - eagle vs crows` | Dance Gavin Dance - Eagle Vs Crows (ver 2 by ed.garnett28).gp
Dance Gavin Dance - Eagle Vs Crows.gp5 | +| `dance gavin dance - flash` | Dance Gavin Dance - Flash (ver 2 by RiseAgainst34).gp
Dance Gavin Dance - Flash.gp5 | +| `dance gavin dance - happiness` | Dance Gavin Dance - Happiness (ver 2 by dylanure2005).gp5
Dance Gavin Dance - Happiness.gpx | +| `dance gavin dance - heat seeking ghost of sex` | Dance Gavin Dance - Heat Seeking Ghost Of Sex (ver 2 by kingshaunicus).gp5
Dance Gavin Dance - Heat Seeking Ghost Of Sex.gp5 | +| `dance gavin dance - hot water on wool` | Dance Gavin Dance - Hot Water On Wool (ver 2 by jakebohn81).gpx
Dance Gavin Dance - Hot Water On Wool.gp4 | +| `dance gavin dance - its safe to say you dig the backseat` | Dance Gavin Dance - Its Safe To Say You Dig The Backseat (ver 2).gp5
Dance Gavin Dance - Its Safe To Say You Dig The Backseat.gp5 | +| `dance gavin dance - long nights in jail` | Dance Gavin Dance - Long Nights In Jail (ver 2 by raviolimaster).gp5
Dance Gavin Dance - Long Nights In Jail.gp5 | +| `dance gavin dance - lyrics lie` | Dance Gavin Dance - Lyrics Lie (ver 2 by president100).gp5
Dance Gavin Dance - Lyrics Lie.gp5 | +| `dance gavin dance - nothing shameful` | Dance Gavin Dance - Nothing Shameful (ver 2 by president100).gp5
Dance Gavin Dance - Nothing Shameful.gpx | +| `dance gavin dance - one in a million` | Dance Gavin Dance - One In A Million (ver 2 by Igor0400).gp
Dance Gavin Dance - One In A Million (ver 3 by president100).gp5 | +| `dance gavin dance - philosopher king` | Dance Gavin Dance - Philosopher King (ver 2 by ed.garnett28).gp
Dance Gavin Dance - Philosopher King.gp | +| `dance gavin dance - polka dot dobbins` | Dance Gavin Dance - Polka Dot Dobbins (ver 2 by raviolimaster).gp5
Dance Gavin Dance - Polka Dot Dobbins.gp5 | +| `dance gavin dance - privilously poncheezied` | Dance Gavin Dance - Privilously Poncheezied (ver 2 by edwinal0504).gpx
Dance Gavin Dance - Privilously Poncheezied.gp5 | +| `dance gavin dance - shark dad` | Dance Gavin Dance - Shark Dad.gp
Dance Gavin Dance - Shark Dad.gpx | +| `dance gavin dance - shelf life` | Dance Gavin Dance - Shelf Life (ver 2 by president100).gp5
Dance Gavin Dance - Shelf Life.gpx | +| `dance gavin dance - skyhook` | Dance Gavin Dance - Skyhook (ver 2 by maxtricano).gp
Dance Gavin Dance - Skyhook.gp | +| `dance gavin dance - son of robot` | Dance Gavin Dance - Son Of Robot (ver 2 by president100).gp5
Dance Gavin Dance - Son Of Robot.gp5 | +| `dance gavin dance - strawberry andre` | Dance Gavin Dance - Strawberry Andre (ver 2 by GonchDog).gp5
Dance Gavin Dance - Strawberry Andre.gp5 | +| `dance gavin dance - stroke god millionaire` | Dance Gavin Dance - Stroke God Millionaire (ver 2 by ed.garnett28).gp
Dance Gavin Dance - Stroke God Millionaire.gp5 | +| `dance gavin dance - surprise im from cuba everyone has one brain` | Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain (ver 2 by GonchDog).gp5
Dance Gavin Dance - Surprise Im From Cuba Everyone Has One Brain.gp5 | +| `dance gavin dance - suspended in this disaster` | Dance Gavin Dance - Suspended In This Disaster (ver 2 by president100).gp5
Dance Gavin Dance - Suspended In This Disaster.gpx | +| `dance gavin dance - the ghost of billy royalton` | Dance Gavin Dance - The Ghost Of Billy Royalton (ver 2 by m.najera.ve).gp5
Dance Gavin Dance - The Ghost Of Billy Royalton.gp5 | +| `dance gavin dance - tree village` | Dance Gavin Dance - Tree Village (ver 2 by ed.garnett28).gp
Dance Gavin Dance - Tree Village.gp5 | +| `dance gavin dance - uneasy hearts weigh the most` | Dance Gavin Dance - Uneasy Hearts Weigh The Most (ver 2).gp
Dance Gavin Dance - Uneasy Hearts Weigh The Most.gp5 | +| `dance gavin dance - variation` | Dance Gavin Dance - Variation (ver 2 by Dio10101).gpx
Dance Gavin Dance - Variation.gpx | +| `dance gavin dance - we own the night` | Dance Gavin Dance - We Own The Night (ver 2 by mstumpfig).gpx
Dance Gavin Dance - We Own The Night.gp5 | +| `hail the sun - black serotonin` | Hail The Sun - Black Serotonin (ver 2 by thursday21987).gp
Hail The Sun - Black Serotonin.gp5 | +| `hail the sun - chunker` | Hail The Sun - Chunker (ver 2 by ry.schenck).gp
Hail The Sun - Chunker.gp | +| `hail the sun - disappearing syndrome` | Hail The Sun - Disappearing Syndrome (ver 2 by thursday21987).gp
Hail The Sun - Disappearing Syndrome.gp | +| `hail the sun - human target practice` | Hail The Sun - Human Target Practice (ver 2 by thursday21987).gp
Hail The Sun - Human Target Practice.gp | +| `hail the sun - missed injections` | Hail The Sun - Missed Injections (ver 2 by thursday21987).gp
Hail The Sun - Missed Injections.gp | +| `hail the sun - mourning sickness` | Hail The Sun - Mourning Sickness (ver 2 by thursday21987).gp
Hail The Sun - Mourning Sickness.gp | +| `hail the sun - never kill a mouse let it kill itself` | Hail The Sun - Never Kill A Mouse Let It Kill Itself (ver 2).gp5
Hail The Sun - Never Kill A Mouse Let It Kill Itself.gp4 | +| `hail the sun - rolling out the red carpet` | Hail The Sun - Rolling Out The Red Carpet (ver 2 by thursday21987).gp
Hail The Sun - Rolling Out The Red Carpet.gpx | +| `hail the sun - will they blame me if you go disappearing` | Hail The Sun - Will They Blame Me If You Go Disappearing (ver 2 by Wicked Strum).gp5
Hail The Sun - Will They Blame Me If You Go Disappearing.gp5 | +| `underoath - a message for adrienne` | Underoath - A Message For Adrienne (ver 2).gp5
Underoath - A Message For Adrienne.gp4 | +| `underoath - breathing in a new mentality` | Underoath - Breathing In A New Mentality (ver 2 by zachemtak).gp5
Underoath - Breathing In A New Mentality.gp5 | +| `underoath - desperate times desperate measures` | Underoath - Desperate Times Desperate Measures (ver 2 by bloodlustx36).gp5
Underoath - Desperate Times Desperate Measures.gp5 | +| `underoath - down set go` | Underoath - Down Set Go (ver 2 by LookIntotheAir).gp5
Underoath - Down Set Go.gp5 | +| `underoath - everyone looks so good from here` | Underoath - Everyone Looks So Good From Here (ver 2 by seanwatson18).gp5
Underoath - Everyone Looks So Good From Here.gp4 | +| `underoath - im content with losing` | Underoath - Im Content With Losing (ver 2 by kikiu).gp5
Underoath - Im Content With Losing.gp4 | +| `underoath - its dangerous business walking out your front door` | Underoath - Its Dangerous Business Walking Out Your Front Door.gp4
Underoath - Its Dangerous Business Walking Out Your Front Door.gp5 | +| `underoath - ive got ten friends and a crowbar that says you aint gonna do jack` | Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack (ver 2 by LookIntotheAir).gp5
Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4 | +| `underoath - last` | Underoath - Last (ver 2 by catalan123).gp5
Underoath - Last.gp5 | +| `underoath - never meant to break your heart` | Underoath - Never Meant To Break Your Heart (ver 2 by @xel).gp5
Underoath - Never Meant To Break Your Heart.gp4 | +| `underoath - to whom it may concern` | Underoath - To Whom It May Concern (ver 2 by n.schulz29).gpx
Underoath - To Whom It May Concern.gp5 | +| `underoath - too bright to see too loud to hear` | Underoath - Too Bright To See Too Loud To Hear (ver 2 by jayman5671).gp5
Underoath - Too Bright To See Too Loud To Hear.gp5 | +| `underoath - young and aspiring` | Underoath - Young And Aspiring (ver 2 by _Doggy_).gp5
Underoath - Young And Aspiring.gp4 | +| `underoath - youre ever so inviting` | Underoath - Youre Ever So Inviting (ver 2 by josh-josh-josh).gpx
Underoath - Youre Ever So Inviting.gp5 | + +
+ +## Annotation coverage + +| Field | Present | Coverage | +| --- | --- | --- | +| `structure` | 9907 | 100.0% | +| `gesture` | 9907 | 100.0% | +| `complexity` | 9907 | 100.0% | +| `rights` | 9907 | 100.0% | +| `style_cohort` | 9907 | 100.0% | +| `duplicate` | 2537 | 25.6% | +| `ensemble` | 9717 | 98.1% | + +## Ensemble integrity + +| Fact | Value | +| --- | --- | +| groups (all manifests) | 405 | +| group member ids | 9717 | +| chunks with ensemble ref | 9717 | +| broken member refs | 0 | +| orphan ensemble refs | 0 | + +## Duplicates & formats + +Content-duplicate tab groups (identical bytes, different paths): **1**. + +- tabs/Underoath - I Got 10 Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4 == tabs/Underoath - Ive Got Ten Friends And A Crowbar That Says You Aint Gonna Do Jack.gp4 + +Source format distribution (chunks): + +| Format | Chunks | +| --- | --- | +| gp | 2105 | +| gp3 | 18 | +| gp4 | 748 | +| gp5 | 5632 | +| gpx | 1404 | + +## Reading + +The corpus is fully **measured** (structure / gesture / complexity / rights) but sits at the **weakest source-identity level**: every manifest is schema v8, so `sha256` and `track_index` are absent everywhere. The fail-closed holdout contracts (Phase-0 audit; ADR-0031) therefore currently block on the whole corpus — the immediate prerequisite is the **v9 `sha256` backfill**, then **v10 `song_id`** curation. The multi-transcription works above are the concrete leakage ADR-0031 addresses. The two-manifest split (a small curated set and a large ingest set) is the real shape the migration must handle.