# AUTHORED-BY Claude Opus 4.8 (Fable unavailable) — re-review/upgrade candidate # @prefix media: . @prefix core: . @prefix owl: . @prefix rdf: . @prefix rdfs: . @prefix xsd: . @prefix dcterms: . @prefix skos: . @prefix vann: . @prefix gufo: . @prefix foaf: . @prefix fedgen: . # ============================================================================= # Solid Media & Activity sector ontology — RE-BASED onto gUFO (KEY=media). # # v1.0.0 re-base of the v0 thin media sector, per R11 §4.2 (the MEDIA row). # Every sector class now carries its own gUFO meta-type AND rdfs:subClassOf a # re-based Core class (contract rule 2): CreativeWork + work types = gufo:SubKind # rooting in core:InformationResource (CreativeWork also rdfs:subClassOf # core:Asset — a licensable work); Artist = gufo:RoleMixin of core:Agent (a # Person or Organization is an artist only while credited); ListeningActivity / # PlaybackEvent = gufo:EventType under core:Activity / core:Event; # ListeningHistory = gufo:SubKind of core:Record (the Spotify export, about the # listener); MediaAccount = relator gufo:SubKind of core:Account; UsageLicense = # relator gufo:SubKind of core:Relationship; Playlist = a SubKind over a curated # collection. MusicGroup = gufo:SubKind of core:Organization that PLAYS the # Artist role (a rigid Kind does NOT subclass the anti-rigid Artist RoleMixin). # # AUTHORING PROVENANCE: authored as an OntoUML model (media.ontouml.json), # verified anti-pattern-free by OntoumlVerification.verify() (F3, 0 issues), # transformed to a gUFO-OWL backbone by ontouml-js Ontouml2Gufo (media.gufo.ttl), # then ENRICHED here with F1 definitions, the Core rooting (rdfs:subClassOf # core:* — the standalone OntoUML model used Core stubs in the media: namespace, # replaced here by the real core: IRIs) and the property spine. # # CONTRACT (R8 §4 + R11 F1-F7) — admissible because: (1) imports the Core; # (2) every class roots in a Core class and carries its gUFO meta-type; # (3) constrains, never forks; (4) reuses schema.org in the companion # media-alignments.ttl; (5) ships media.shacl.ttl; (6) carries owl:versionInfo # "1.0.0" + a version IRI (gUFO re-base = new MAJOR); (7) Core ∪ media is # DL-valid + reasoner-consistent (see verification report). Open-world by # default; the SHACL profile carries the closed-world MUST/SHOULD. # # gUFO-DISJOINTNESS NOTE: core:about has domain core:InformationResource and # range gufo:Endurant; gUFO holds endurants and events disjoint. The # event-domain "what was played/consumed" links (media:playedWork, # media:consumedWork) are therefore PLAIN object properties, NOT sub-properties # of core:about — sub-propertying them would force PlaybackEvent/ListeningActivity # ⊑ core:InformationResource and make those event classes unsatisfiable. Only the # endurant-domain media:recordingOf is rooted in core:about. # ============================================================================= a owl:Ontology ; dcterms:title "Solid Media & Activity Ontology (gUFO re-base)"@en ; rdfs:label "Solid Media & Activity Ontology"@en ; vann:preferredNamespacePrefix "media" ; vann:preferredNamespaceUri "https://w3id.org/jeswr/sectors/media#" ; owl:imports ; owl:versionInfo "1.0.0" ; owl:versionIRI ; dcterms:description """Media consumption & creative works — the Spotify end-to-end example and the media importers — re-based onto the gUFO Core. Roots in core:InformationResource/core:Asset (creative works), core:Agent (the Artist role), core:Activity/core:Event (listening / playback), core:Record (the imported listening history about the listener), core:Account (the streaming account) and core:Relationship (the usage licence). v1.0.0 is a BREAKING re-base of v0 (the meta-types change meaning), so a new MAJOR version. Aligns to schema.org CreativeWork/MusicRecording/MusicGroup/Event and ODRL in the companion alignments file."""@en ; dcterms:modified "2026-06-13"^^xsd:date ; rdfs:comment "Re-based per R11 §4.2."@en . # ----------------------------------------------------------------------------- # Annotation-property declarations (F5: keep the merged closure unambiguously # OWL 2 DL — declare the dcterms:/vann: annotation properties used here). # ----------------------------------------------------------------------------- dcterms:title a owl:AnnotationProperty . dcterms:description a owl:AnnotationProperty . dcterms:modified a owl:AnnotationProperty . vann:preferredNamespacePrefix a owl:AnnotationProperty . vann:preferredNamespaceUri a owl:AnnotationProperty . skos:definition a owl:AnnotationProperty . skos:scopeNote a owl:AnnotationProperty . fedgen:deliberatelyUnconstrained a owl:AnnotationProperty . # ============================================================================= # 1. CREATIVE WORKS (gufo:SubKind rooting in core:InformationResource) # A creative work is an information object that, when licensable, is also a # core:Asset (matching core:Asset's own "a licensed track" example). Both are # asserted on CreativeWork; this does NOT collapse the two Core classes (no # owl:equivalentClass between them) — instances simply participate in both. # ============================================================================= media:CreativeWork a owl:Class, gufo:SubKind ; rdfs:subClassOf core:InformationResource , core:Asset ; rdfs:label "Creative Work"@en ; skos:definition "A work of authorship — a recording, album, podcast episode, video, or other media item. An information object that, when licensable, is also a core:Asset. Aligns to schema:CreativeWork."@en ; skos:scopeNote "gufo:SubKind under core:InformationResource (its identity principle) and core:Asset."@en . media:MusicRecording a owl:Class, gufo:SubKind ; rdfs:subClassOf media:CreativeWork ; rdfs:label "Music Recording"@en ; skos:definition "A single recorded performance of a composition — the played unit in a streaming service. Aligns to schema:MusicRecording."@en ; skos:scopeNote "gufo:SubKind of media:CreativeWork."@en . media:Track a owl:Class, gufo:SubKind ; rdfs:subClassOf media:MusicRecording ; rdfs:label "Track"@en ; skos:definition "A music recording as it appears as a playable track on a service (the Spotify-style 'track'), carrying service-level identifiers."@en ; skos:scopeNote "gufo:SubKind of media:MusicRecording."@en . media:MusicComposition a owl:Class, gufo:SubKind ; rdfs:subClassOf media:CreativeWork ; rdfs:label "Music Composition"@en ; skos:definition "The underlying musical work (songwriting/score) that a recording is a recording of. Aligns to schema:MusicComposition."@en ; skos:scopeNote "gufo:SubKind of media:CreativeWork."@en . media:Album a owl:Class, gufo:SubKind ; rdfs:subClassOf core:InformationResource ; rdfs:label "Album"@en ; skos:definition "A released collection of recordings; its tracks are core:hasPart of it. A curated collection whole. Aligns to schema:MusicAlbum."@en ; skos:scopeNote "gufo:SubKind of core:InformationResource (collection whole)."@en . media:Playlist a owl:Class, gufo:SubKind ; rdfs:subClassOf core:InformationResource ; rdfs:label "Playlist"@en ; skos:definition "A curated, ordered collection of recordings assembled by a Person or service; its entries are core:hasPart of it. A SubKind over a collection. Aligns to schema:MusicPlaylist."@en ; skos:scopeNote "gufo:SubKind of core:InformationResource (collection whole)."@en . media:PodcastEpisode a owl:Class, gufo:SubKind ; rdfs:subClassOf media:CreativeWork ; rdfs:label "Podcast Episode"@en ; skos:definition "A single episode of a podcast — a spoken-audio creative work. Aligns to schema:PodcastEpisode."@en ; skos:scopeNote "gufo:SubKind of media:CreativeWork."@en . # ============================================================================= # 2. ARTIST (gufo:RoleMixin of core:Agent) # The role an Agent plays when credited as creator/performer of a work. # Anti-rigid (an agent is an artist only while credited) and cross-kind (a solo # artist is a core:Person, a band a core:Organization) — hence a RoleMixin, # rooted at core:Agent precisely so it does not collapse Person and Organization. # ============================================================================= media:Artist a owl:Class, gufo:RoleMixin ; rdfs:subClassOf core:Agent ; rdfs:label "Artist"@en ; rdfs:seeAlso foaf:name ; skos:definition "The role of an agent (a core:Person or a core:Organization) credited as the creator/performer of a creative work. Rooted in core:Agent so both solo artists and bands qualify without collapsing those Core classes."@en ; skos:scopeNote "gufo:RoleMixin (anti-rigid, cross-kind) played by core:Agent. Played by media:MusicGroup and by core:Person. DISPLAY NAME: an artist's literal display name is carried by foaf:name (reuse-before-mint) — the ArtistShape in media.shacl.ttl names it; adopted from the @jeswr/solid-listening fedcon observation so every producer agrees on foaf:name rather than each picking schema:name / rdfs:label."@en . media:MusicGroup a owl:Class, gufo:SubKind ; rdfs:subClassOf core:Organization ; rdfs:label "Music Group"@en ; skos:definition "A band or musical ensemble acting as a single artist — an organization. Plays the media:Artist role. Aligns to schema:MusicGroup."@en ; skos:scopeNote "gufo:SubKind of core:Organization. Plays media:Artist (not a subclass of the anti-rigid Artist RoleMixin — a rigid Kind under an anti-rigid role would be an OntoUML anti-pattern)."@en . # ============================================================================= # 3. CONSUMPTION (gufo:EventType under core:Activity / core:Event) # A listen is performed over time (ListeningActivity, a core:Activity, # core:performedBy the listener) and also occurs as a datable happening # (PlaybackEvent, a core:Event, core:hadParticipant the listener). Distinct, # linkable facets — neither redefines a Core class. # ============================================================================= media:ListeningActivity a owl:Class, gufo:EventType ; rdfs:subClassOf core:Activity ; rdfs:label "Listening Activity"@en ; skos:definition "An agent's act of consuming a creative work over time (listening to a track, watching a video). core:performedBy the listener. Aligns to schema:ListenAction (a schema:ConsumeAction)."@en ; skos:scopeNote "gufo:EventType (its instances are gufo:Event perdurants) under core:Activity."@en . media:PlaybackEvent a owl:Class, gufo:EventType ; rdfs:subClassOf core:Event ; rdfs:label "Playback Event"@en ; skos:definition "A single datable play occurrence — WHAT was played (media:playedWork), WHEN (core:atTime), and on which Account (media:onAccount). core:hadParticipant the listener. The atomic row of a streaming history."@en ; skos:scopeNote "gufo:EventType (perdurant) under core:Event."@en . # ============================================================================= # 4. IMPORTED LISTENING HISTORY (gufo:SubKind of core:Record) # An imported export (a Spotify data dump) is a Record core:about / core:subject # the listener, aggregating PlaybackEvents via core:hasPart. The Spotify e2e tie. # ============================================================================= media:ListeningHistory a owl:Class, gufo:SubKind ; rdfs:subClassOf core:Record ; rdfs:label "Listening History"@en ; skos:definition "An imported record of a person's media consumption (e.g. a Spotify data export). core:subject the listener; aggregates PlaybackEvents via core:hasPart. The imported listening record about the Person."@en ; skos:scopeNote "gufo:SubKind of core:Record."@en . # ============================================================================= # 5. MEDIA ACCOUNT (relator gufo:SubKind of core:Account) # A standing streaming account; a reified relator carrying the holder and # provider via the Core's Account mediations (core:hasAccountHolder / # core:hasAccountProvider). No new mediation minted. # ============================================================================= media:MediaAccount a owl:Class, gufo:SubKind ; rdfs:subClassOf core:Account ; rdfs:label "Media Account"@en ; skos:definition "A standing account with a media/streaming service through which a person consumes works (a Spotify account). A reified relator: core:hasAccountHolder the person, core:hasAccountProvider the service."@en ; skos:scopeNote "gufo:SubKind of core:Account (relator). Reuses the Core's Account mediations."@en . # ============================================================================= # 6. USAGE LICENCE (relator gufo:SubKind of core:Relationship) — ODRL tie (R2) # A reified grant of usage rights over a work, between rights-holder and # beneficiary, carrying validity and terms. Parties via the Core's # core:relatesParty mediation; conceptual tie to ODRL usage control (R2). # ============================================================================= media:UsageLicense a owl:Class, gufo:SubKind ; rdfs:subClassOf core:Relationship ; rdfs:label "Usage License"@en ; skos:definition "A reified grant of usage rights over a creative work, between a rights-holder and a beneficiary, with validity and terms. Conceptually ties to ODRL usage control (R2); aligns to schema:license."@en ; skos:scopeNote "gufo:SubKind of core:Relationship (relator). Parties via core:relatesParty; the licensed work via media:licensedWork."@en . # ============================================================================= # Properties — sub-properties of Core where one fits (constrain, never widen). # Event/relator-domain "what" links are PLAIN properties (see disjointness note). # ============================================================================= # --- crediting works to artists --- media:performedByArtist a owl:ObjectProperty ; rdfs:subPropertyOf core:custodian ; rdfs:domain media:CreativeWork ; rdfs:range media:Artist ; rdfs:label "performed by artist"@en ; skos:definition "The artist credited with creating/performing a work. A sub-property of core:custodian (the agent controlling/holding the work) narrowed to the artist credit. Aligns to schema:byArtist."@en . # --- recording -> composition (endurant domain: safe under core:about) --- media:recordingOf a owl:ObjectProperty ; rdfs:subPropertyOf core:about ; rdfs:domain media:MusicRecording ; rdfs:range media:MusicComposition ; rdfs:label "recording of"@en ; skos:definition "The composition that a recording is a recording of. A sub-property of core:about (the recording, an information object, is about the composition). Aligns to schema:recordingOf."@en . # --- structural membership (sub-properties of core:partOf, transitive) --- media:inAlbum a owl:ObjectProperty ; rdfs:subPropertyOf core:partOf ; rdfs:domain media:MusicRecording ; rdfs:range media:Album ; rdfs:label "in album"@en ; skos:definition "The album a recording belongs to. Sub-property of core:partOf. Aligns to schema:inAlbum."@en . media:inPlaylist a owl:ObjectProperty ; rdfs:subPropertyOf core:partOf ; rdfs:domain media:MusicRecording ; rdfs:range media:Playlist ; rdfs:label "in playlist"@en ; skos:definition "A playlist a recording is included in. Sub-property of core:partOf. Aligns to schema:inPlaylist."@en . # --- the consumption act: what was played / consumed (event-domain: PLAIN) --- media:playedWork a owl:ObjectProperty ; rdfs:domain media:PlaybackEvent ; rdfs:range media:CreativeWork ; rdfs:label "played work"@en ; skos:definition "The creative work that was played in this playback event (the WHAT). A plain object property: PlaybackEvent is a gufo:Event, so this is NOT a sub-property of core:about (whose domain core:InformationResource is gUFO-disjoint from events)."@en . media:consumedWork a owl:ObjectProperty ; rdfs:domain media:ListeningActivity ; rdfs:range media:CreativeWork ; rdfs:label "consumed work"@en ; skos:definition "The creative work consumed during a listening activity. A plain object property for the same gUFO-disjointness reason as media:playedWork. Aligns to schema:object of the ListenAction."@en . media:onAccount a owl:ObjectProperty ; rdfs:domain media:PlaybackEvent ; rdfs:range media:MediaAccount ; rdfs:label "on account"@en ; skos:definition "The media account through which a playback occurred."@en . # --- usage licence wiring (relator domain: PLAIN, not core:about) --- media:licensedWork a owl:ObjectProperty ; rdfs:domain media:UsageLicense ; rdfs:range media:CreativeWork ; rdfs:label "licensed work"@en ; skos:definition "The creative work a usage licence applies to. A plain object property: UsageLicense is a gufo:Relator, distinct from core:InformationResource, so it is NOT a sub-property of core:about."@en . media:hasLicense a owl:ObjectProperty ; rdfs:domain media:CreativeWork ; rdfs:range media:UsageLicense ; rdfs:label "has license"@en ; skos:definition "A usage licence that applies to this creative work. Aligns to schema:license."@en . # --- datatype properties (literal-level service metadata) --- media:isrc a owl:DatatypeProperty ; rdfs:domain media:MusicRecording ; rdfs:range xsd:string ; rdfs:label "ISRC"@en ; skos:definition "International Standard Recording Code for a recording. Aligns to schema:isrcCode. For scheme-anchored identifiers prefer core:identifiedBy + core:Identifier."@en . media:durationSeconds a owl:DatatypeProperty ; rdfs:domain media:CreativeWork ; rdfs:range xsd:decimal ; rdfs:label "duration (seconds)"@en ; skos:definition "Playable duration of a work in seconds. A literal shortcut; schema:duration (ISO-8601) is the aligned external term."@en . media:msPlayed a owl:DatatypeProperty ; rdfs:domain media:PlaybackEvent ; rdfs:range xsd:integer ; rdfs:label "milliseconds played"@en ; skos:definition "How long the work was actually played in this event, in milliseconds (the Spotify-export 'ms_played' field). Distinguishes a skip from a full listen."@en . media:licenseTerms a owl:DatatypeProperty ; rdfs:domain media:UsageLicense ; rdfs:range xsd:string ; rdfs:label "license terms"@en ; skos:definition "Human-readable summary of the licence terms. Machine-actionable terms SHOULD be expressed via an ODRL policy (R2) referenced from the licence."@en . # ============================================================================= # 7. LISTENING-FORK EXTENSIONS — playback-event terms ADMITTED from the # @jeswr/solid-listening fedcon:Proposal candidates (a Web Scrobbler→Solid fork, # listening.proposals.ttl). Modelling REAL scrobble data surfaced these gaps; the # fork drove them through the contribution lifecycle and the sector now adopts # them ADDITIVELY (constrain-never-fork). All three are per-play event metadata on # media:PlaybackEvent, so they root there. See media.shacl.ttl for the graded # profile (all Info — optional, well-formedness-only). # ============================================================================= # --- completion fraction (fedcon #prop-completion) --- media:completionFraction a owl:DatatypeProperty ; rdfs:domain media:PlaybackEvent ; rdfs:range xsd:decimal ; rdfs:label "completion fraction"@en ; skos:definition "The fraction of the work played in this event, in [0,1]. Source-independent — unlike deriving it from media:msPlayed / media:durationSeconds (a live stream has no durationSeconds), so it can express 'how much' even when the total length is unknown. Adopted from the @jeswr/solid-listening fedcon proposal (Web Scrobbler full-listen-vs-skip need)."@en . # --- source-service attribution (fedcon #prop-played-via) --- media:playedVia a owl:ObjectProperty ; rdfs:domain media:PlaybackEvent ; fedgen:deliberatelyUnconstrained "The service/platform target is deliberately open — a service IRI (e.g. a platform identifier) OR a labelled node — so no rdfs:range is asserted (F-waiver)." ; rdfs:label "played via"@en ; skos:definition "The media service / platform a play occurred on (YouTube Music, Spotify web, SoundCloud, a radio site), as a service IRI or a labelled node. Distinct from media:onAccount — a play can be attributed to a service with no known media:MediaAccount (the common Web Scrobbler case: an anonymous web player). Adopted from the @jeswr/solid-listening fedcon proposal."@en . # --- loved flag (fedcon #prop-loved-skipped) --- media:loved a owl:DatatypeProperty ; rdfs:domain media:PlaybackEvent ; rdfs:range xsd:boolean ; rdfs:label "loved"@en ; skos:definition "Whether the user marked this play/track as loved (the Web Scrobbler 'love' affordance) — first-class per-play user feedback, not inferred from media:msPlayed. Adopted from the @jeswr/solid-listening fedcon proposal."@en . # ============================================================================= # SECTOR MARKER — the IRI an app's fedapp:sector points at to declare it operates # in this sector (https://w3id.org/jeswr/fed#sector). A skos:Concept in the # federation sector register; dereferences to this ontology. # ============================================================================= a ; rdfs:label "Media & Activity sector"@en ; rdfs:comment "The Media & Activity data sector. The value an app's fedapp:sector names in its Client Identifier Document to declare it operates over media & activity data. Backed by this sector ontology."@en ; rdfs:isDefinedBy ; skos:prefLabel "Media & Activity"@en .