# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-FileCopyrightText: 2026 Agilit Ltd @prefix owl: . @prefix rdf: . @prefix rdfs: . @prefix xsd: . @prefix dcterms: . @prefix skos: . @prefix vann: . @prefix prov: . @prefix sh: . @prefix ies: . @prefix marvin: . # ========================================================================== # Ontology declaration # ========================================================================== a owl:Ontology ; dcterms:title "Marvin Memory Graph Ontology"@en-gb ; dcterms:description """An IES v5 extension defining the schema for the Marvin Memory Graph: the persistent knowledge graph that serves as the brain of the Marvin AI-augmented ontology development environment. Marvin models the ontology development process itself: artefacts, decisions, rationale, rejected alternatives, unresolved tensions, competency questions, consumer-view projections, and provenance. """@en-gb ; dcterms:created "2026"^^xsd:gYear ; dcterms:modified "2026-05-17"^^xsd:date ; dcterms:publisher "Agilit Ltd"@en-gb ; dcterms:rights "Agilit Ltd 2026"@en-gb ; dcterms:license ; dcterms:rightsHolder "Agilit Ltd" ; vann:preferredNamespacePrefix "marvin" ; vann:preferredNamespaceUri "https://w3id.org/marvin/" ; owl:versionInfo "0.2.15" ; owl:versionIRI ; owl:imports ; skos:note """Dependency: marvin:criterionSeverity uses sh:Severity from SHACL. See ontology/VALIDATION.md for details. """@en-gb . # ========================================================================== # SECTION A -- OntologyArtefact hierarchy # ========================================================================== marvin:OntologyArtefact a rdfs:Class ; rdfs:label "Ontology Artefact"@en-gb ; dcterms:identifier "{F3A2B1C4-9D8E-4F7A-B6C5-2E1D0A3F4B5C}" ; rdfs:comment """An Asset representing a constituent part of one or more IES ontology modules as tracked in the Marvin Memory Graph. Superclass for all existence-layer node types. Follows the IES 4D pattern: OntologyArtefact is simultaneously a subclass of ies:Asset (whole-life lineage) and a subclass of marvin:OntologyArtefactState (whole-life entity = all-time state). Compare ies:Person rdfs:subClassOf ies:PersonState, ies:ResponsibleActor. """@en-gb ; ies:powertype marvin:ClassOfOntologyArtefact ; rdfs:subClassOf ies:Asset, marvin:OntologyArtefactState . marvin:ClassOfOntologyArtefact a rdfs:Class ; rdfs:label "Class Of Ontology Artefact"@en-gb ; dcterms:identifier "{A1B2C3D4-E5F6-4A7B-8C9D-0E1F2A3B4C5D}" ; rdfs:comment """The powertype of OntologyArtefact: a ClassOfEntity whose instances are classes of OntologyArtefact. Subclasses are the taxonomy classes that classify OntologyArtefact instances. """@en-gb ; rdfs:subClassOf ies:ClassOfAsset . marvin:OntologyArtefactState a rdfs:Class ; rdfs:label "Ontology Artefact State"@en-gb ; dcterms:identifier "{B2C3D4E5-F6A7-4B8C-9D0E-1F2A3B4C5D6E}" ; rdfs:comment """A temporal state of an OntologyArtefact. Existence-layer taxonomies (e.g. SyncStatus, IESVersion) classify states of OntologyArtefact rather than the whole-life entity, enabling point-in-time queries and a complete audit trail via ies:isStateOf. """@en-gb ; ies:powertype marvin:ClassOfOntologyArtefactState ; rdfs:subClassOf ies:AssetState . marvin:ClassOfOntologyArtefactState a rdfs:Class ; rdfs:label "Class Of Ontology Artefact State"@en-gb ; dcterms:identifier "{C3D4E5F6-A7B8-4C9D-0E1F-2A3B4C5D6E7F}" ; rdfs:comment """The powertype of OntologyArtefactState. Taxonomy classes that classify existence-layer states subclass this. Note: ies:ClassOfAssetState is not defined in IES Common v5; ies:ClassOfState is used as the parent. """@en-gb ; rdfs:subClassOf ies:ClassOfState . # ========================================================================== # SECTION B -- Existence-layer classes # ========================================================================== marvin:OntologyLayer a rdfs:Class ; rdfs:label "Ontology Layer"@en-gb ; dcterms:identifier "{2DD644D4-61B9-4282-817D-48A069EC809D}" ; rdfs:comment """An OntologyArtefact representing a named architectural layer in IES: Top, Core, or a Domain layer. Layers contain OntologyModules (ies:isPartOf). """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . marvin:OntologyModule a rdfs:Class ; rdfs:label "Ontology Module"@en-gb ; dcterms:identifier "{E5C76C6D-7C24-4871-A90D-FE27EF0BAE36}" ; rdfs:comment """An OntologyArtefact representing a deployable ontology unit: typically one .ttl file managed in a GitHub repository. Belongs to one OntologyLayer via ies:isPartOf. """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . marvin:ClassNode a rdfs:Class ; rdfs:label "Class Node"@en-gb ; dcterms:identifier "{A8635877-D113-4749-A6EE-5E56A81A6C45}" ; rdfs:comment """An OntologyArtefact representing an owl:Class defined in a target IES module. Existence-layer; auto-synced. Carries URI, label, comment, dcterms:identifier, subclass relationships, and sync status. Decision rationale is in decision-layer nodes linked via marvin:concernsArtefact. """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . marvin:PropertyNode a rdfs:Class ; rdfs:label "Property Node"@en-gb ; dcterms:identifier "{12858468-280A-45EA-A04A-1B56029D5C26}" ; rdfs:comment """An OntologyArtefact representing an owl:ObjectProperty or owl:DatatypeProperty defined in a target IES module. Existence-layer; auto-synced. """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . marvin:AxiomNode a rdfs:Class ; rdfs:label "Axiom Node"@en-gb ; dcterms:identifier "{5273195E-0650-42C1-8061-F3D6271F9702}" ; rdfs:comment """An OntologyArtefact representing a specific logical constraint in a target IES module: domain/range, subClassOf, equivalentClass, etc. Existence-layer; auto-synced. Identity. AxiomNode does NOT carry marvin:artefactSlug. Its identity is its (subject, predicate, object) triple; the IRI template (Section L) encodes the SPO directly via {subject-slug}, {predicate-local}, {object-slug}. See Issue #53 for the full rationale. """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . marvin:NamespaceNode a rdfs:Class ; rdfs:label "Namespace Node"@en-gb ; dcterms:identifier "{236D57ED-1946-4D5C-A23E-9282E003495F}" ; rdfs:comment """An OntologyArtefact representing a declared namespace/prefix binding in a target IES module. Existence-layer; auto-synced. """@en-gb ; rdfs:subClassOf marvin:OntologyArtefact . # ========================================================================== # SECTION C -- Decision-layer classes # ========================================================================== marvin:DevelopmentDecision a rdfs:Class ; rdfs:label "Development Decision"@en-gb ; dcterms:identifier "{03F2FE2D-DB29-4128-BFE2-BD43C181D992}" ; rdfs:comment """An AssessToBeTrue representing a committed design choice made during ontology development. Carries provenance (who, when, confidence) and links to rejected alternatives. Decision content — the committed design choice — is modelled as the whole-life entity and is immutable. When the deliberation later adopts a different decision in its place, the supersession is recorded with marvin:supersededBy (this decision -> the superseding one) and this decision's adopted-position marvin:DevelopmentDecisionState is closed under DD-005 Pattern B; whether a decision is still in force is read from that bounding topology (DD-016), not from a flag. ies:successorTo is NOT used for DevelopmentDecision supersession — see DD-019 for the category analysis. A/B party status and information completeness are properties of the epistemic context at the time the decision was made. Changes in either produce a new marvin:DevelopmentDecisionState (not a new decision), supporting a clean audit trail. See ClassOfDevelopmentDecisionStateByABStatus and ClassOfDevelopmentDecisionStateByInfoCompleteness. """@en-gb ; ies:powertype marvin:ClassOfDevelopmentDecision ; rdfs:subClassOf ies:AssessToBeTrue, prov:Entity . marvin:ClassOfDevelopmentDecision a rdfs:Class ; rdfs:label "Class Of Development Decision"@en-gb ; dcterms:identifier "{D4E5F6A7-B8C9-4D0E-1F2A-3B4C5D6E7F8A}" ; rdfs:comment """The powertype of DevelopmentDecision. AssessToBeTrue subclasses Assessment which subclasses Event; ies:ClassOfEvent is therefore the correct parent in the IES ClassOfElement hierarchy. """@en-gb ; rdfs:subClassOf ies:ClassOfEvent . marvin:DevelopmentDecisionState a rdfs:Class ; rdfs:label "Development Decision State"@en-gb ; dcterms:identifier "{E5F6A7B8-C9D0-4E1F-2A3B-4C5D6E7F8A9B}" ; rdfs:comment """A temporal state of a DevelopmentDecision. Carries the A/B party grounding status and information completeness classification for the period during which they held. Using states rather than whole-life classification reflects that AB grounding and information completeness are properties of the epistemic context at a point in time, not constitutive of the decision content. A change in either creates a new state of the same decision (not a new decision), supporting audit trail queries. Successive states must be linked via ies:after (earlier state as subject, later as object) by the pipeline. Do NOT rely on manual assertion of ies:after — see VALIDATION.md. """@en-gb ; ies:powertype marvin:ClassOfDevelopmentDecisionState ; rdfs:subClassOf ies:EventState . marvin:ClassOfDevelopmentDecisionState a rdfs:Class ; rdfs:label "Class Of Development Decision State"@en-gb ; dcterms:identifier "{F6A7B8C9-D0E1-4F2A-3B4C-5D6E7F8A9B0C}" ; rdfs:comment """The powertype of DevelopmentDecisionState. Taxonomy classes that classify decision states subclass this. Note: ies:ClassOfEventState is not defined in IES Common v5; ies:ClassOfState is used as the parent. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:RejectedAlternative a rdfs:Class ; rdfs:label "Rejected Alternative"@en-gb ; dcterms:identifier "{515599EA-8AB5-4143-8AC9-6C714CCB0823}" ; rdfs:comment """An Assessment representing a candidate design choice that was considered but never adopted. Linked to the adopted decision via marvin:rejectedInFavourOf. Retained permanently -- rejected alternatives are first-class memory. Distinct from marvin:Proposal (a candidate still open, not yet resolved) and from a superseded marvin:DevelopmentDecision (a candidate that was adopted and then replaced -- see marvin:supersededBy): a RejectedAlternative was never adopted. The lowercase wording above is deliberate and asserts no subclass relationship to marvin:Proposal. See DD-020. """@en-gb ; rdfs:subClassOf ies:Assessment, prov:Entity . marvin:OpenTension a rdfs:Class ; rdfs:label "Open Tension"@en-gb ; dcterms:identifier "{D8E6495C-29EF-46D5-9940-A7B91F2CAFD8}" ; rdfs:comment """An Assessment representing a consciously parked disagreement or open question. Whole-life entity. Under DD-012 (v0.2.11), marvin:OpenTension is the whole-life individual representing a tension across all narrowings of its scope. Each narrowing event mints a new marvin:OpenTensionState (linked via ies:isStateOf), carrying the scope-describing rdfs:comment for that state; successive states are linked via prov:wasRevisionOf and bounded by ies:BoundingState instances per Pattern B (DD-005). The whole-life OpenTension's rdfs:comment is identity-descriptive (what the tension is about across all states); scope-describing rdfs:comment literals on OpenTension instances pre-dating DD-012 are retained as historical record under the append-only ledger discipline, with the state-chain layered on top per Section 21 of memory-graph-entries.ttl. Resolution paths under DD-012 (state-chain semantics): * R2 — Focused follow-up issue at the surfacing sub-issue's land time. Latest state closes (Pattern B); successor DD recorded via ies:successorTo on the whole-life or on the terminal state. * R3 — Partial narrowing. Latest state's scope narrows to a successor state at narrower scope; the predecessor state records ies:successorTo to the DD that effected the narrowing; the new state has no closing bound until further narrowing or full resolution. * R4 — Deferral to closure synthesis. Latest state closes (Pattern B); terminal state's ies:successorTo records the closure-synthesis DD. Resolution direction: OpenTension or OpenTensionState ies:successorTo DevelopmentDecision (issue -> resolution, forward in time). See DD-004 for the predicate-level resolution-direction convention, DD-012 for the state-chain reading, and DD-005 for the Pattern B precedent. """@en-gb ; rdfs:subClassOf ies:Assessment, prov:Entity . marvin:OpenTensionState a rdfs:Class ; rdfs:label "Open Tension State"@en-gb ; dcterms:identifier "{4C5D6E7F-8A9B-4C0D-1E2F-3A4B5C6D7E8F}" ; rdfs:comment """A temporal state of a marvin:OpenTension representing a single scope-revision. Carries the scope-describing rdfs:comment for the period during which the scope held, plus marvin:revisionNumber (1-indexed within the (slug,) scope) and a dcterms:created literal recording the assertion-time of the state (distinct from the historical extent the state represents, which is recorded via the opening ies:BoundingState's ies:inPeriod reference). Parallels marvin:CompiledDocumentState (DD-005) and marvin:CorpusFileState (DD-010) Pattern B at the OpenTension layer. Successive states are linked via prov:wasRevisionOf (new state -> old state); narrowing events use Pattern B bounding (closing on the predecessor, opening on the successor, sharing the same ies:ParticularPeriod at the boundary). Partial-narrowing case (R3, per DD-012 Q1). The R3 case is distinct from R2 / R4: the predecessor state is NOT closed with a Pattern B bounding cluster; instead it records ies:successorTo against the DD that effected the narrowing, and a new state at narrower scope opens with no closing bound. The current-scope query under DD-012 must distinguish three outcomes (no-successor-DD vs successor-DD-but-no-closing-bound vs closed-with-successor); see the stylebook entry docs/stylebook/open-tension-lifecycle.md for the query pattern. IRI templates (Section L). Two forms per the worked-example- namespacing convention: Project-level: open-tension-state/{slug}/rev-{n} Worked-example: we:ots-{slug}-rev-{n} where {slug} is the OpenTension's identity-bearing slug body (without `tension-` / `ots-` prefixes used in the worked-example `we:` short forms; see Section L's {slug} variable-semantics entry and the OpenTension template-block prose for the two-form parallel-shape note). Logical- composite over (slug, n) per DD-007's default rule. One stream of states per OpenTension; the two forms are alternatives for the same logical OpenTension under their respective namespace conventions, not parallel IRIs for the same RDF resource. See DD-012 for the full design rationale, DD-005 for the Pattern B precedent, and DD-006 for the commit_atomic boundary discipline that bounding writes rely on. """@en-gb ; ies:powertype marvin:ClassOfOpenTensionState ; rdfs:subClassOf ies:AssetState . marvin:ClassOfOpenTensionState a rdfs:Class ; rdfs:label "Class Of Open Tension State"@en-gb ; dcterms:identifier "{5D6E7F8A-9B0C-4D1E-2F3A-4B5C6D7E8F9A}" ; rdfs:comment """The powertype of marvin:OpenTensionState. Taxonomy classes that classify OpenTension states would subclass this; no such taxonomies are declared at v0.2.11 (DD-012 ships the bare state-class without classifying vocabularies, parallel to marvin:DevelopmentDecisionState's H.4/H.5 vs CorpusFileState's H.6 — the latter has a SyncStatus taxonomy, the former does not). Note: ies:ClassOfAssetState is not defined in IES Common v5; ies:ClassOfState is used as the parent. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:Finding a rdfs:Class ; rdfs:label "Finding"@en-gb ; dcterms:identifier "{9F6ED2E2-1F1F-4351-B581-6251B63DFEEE}" ; rdfs:comment """A single structured observation raised by a reviewer persona during a marvin:ReviewEvent -- the queryable counterpart of a per-persona review note. An ies:Assessment: a reviewer makes a judgement against an artefact. ies:isPartOf its ReviewEvent; marvin:raisedBy the raiser's marvin:AgentRole; marvin:concernsArtefact the artefact judged. Distinct from marvin:RejectedAlternative (a closed design alternative) and marvin:OpenTension (a parked open question), though all three are ies:Assessment subclasses: a Finding records a review-moment observation, not a decision outcome. A Finding is a fixed historical record and has no companion state class. Carries marvin:findingKind and marvin:findingOutcome discriminators (Section H.10 / H.11). Phase 1 design is DD-018; host issue #77. """@en-gb ; rdfs:subClassOf ies:Assessment, prov:Entity . marvin:Proposal a rdfs:Class ; rdfs:label "Proposal"@en-gb ; dcterms:identifier "{64FD1AF8-C680-44F4-9DF3-F1D1407850B6}" ; rdfs:comment """A candidate design choice put forward during ontology development and not yet resolved -- the open-candidate phase of deliberation. An ies:Assessment, a sibling of marvin:DevelopmentDecision and marvin:RejectedAlternative, not their parent: proposing, deciding, and rejecting are distinct events about shared candidate content. A Proposal is open iff it carries neither marvin:adoptedAs nor marvin:rejectedAs. For candidates substantial enough to carry a sketch (marvin:proposalSketch) and rationale and be weighed against siblings -- not every fleeting alternative. A leaf class: no state-chain. Phase 1 design is DD-020; host issue #76. """@en-gb ; rdfs:subClassOf ies:Assessment, prov:Entity . marvin:DevelopmentQuestion a rdfs:Class ; rdfs:label "Development Question"@en-gb ; dcterms:identifier "{1A2B3C4D-5E6F-4A1B-8C9D-0E1F2A3B4C5D}" ; rdfs:comment """A WorkOfDocumentation representing a question posed to the Q&A agent during ontology development. Distinct from marvin:OpenTension (an assessment of an unresolved disagreement) and from marvin:CompetencyQuestion (a testable requirement). A DevelopmentQuestion may be purely informational (answered by a QARecord that carries no committed design choice) or may surface a decision-bearing answer. To find DevelopmentDecisions that arose from a question, query for DevelopmentDecision instances whose marvin:groundedIn links to a QARecord that is the range of marvin:answersQuestion on this question: SELECT ?decision WHERE { marvin:answersQuestion ?qa . ?decision marvin:groundedIn ?qa . } Resolution direction: DevelopmentQuestion marvin:answersQuestion QARecord (issue -> resolution, forward in time). See DD-004. A/B grounding: may be speculative (exploratory questions before a concrete party A/B is identified are acceptable). Flag with marvin:ABStatusSpeculative on the associated DevelopmentDecisionState if a decision results. """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:Principle a rdfs:Class ; rdfs:label "Principle"@en-gb ; dcterms:identifier "{54A48B3A-530B-4336-A3CD-D6F797E667FA}" ; rdfs:comment """An Asset representing a first-class design principle against which proposals can be explicitly evaluated. """@en-gb ; rdfs:subClassOf ies:Asset . marvin:CompetencyQuestion a rdfs:Class ; rdfs:label "Competency Question"@en-gb ; dcterms:identifier "{BDD81BEB-4A2B-4142-97DD-7CEF4C3B7BCE}" ; rdfs:comment """A WorkOfDocumentation expressing a requirement as both a natural language narrative (marvin:cqNarrative) and a SPARQL query (marvin:cqSparql). A module satisfies a CQ if the query returns expected results against conforming data. Distinct from marvin:DevelopmentQuestion (an inquiry) and from marvin:OpenTension (a parked disagreement). See DD-004. Resolution direction: CompetencyQuestion marvin:isSatisfiedBy ValidationRun (issue -> resolution, forward in time). See DD-004. """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:ValidationProfile a rdfs:Class ; rdfs:label "Validation Profile"@en-gb ; dcterms:identifier "{A1066AFC-2AD4-4598-8711-7ED61B39E6F2}" ; rdfs:comment """An Asset representing a named, reusable set of ValidationCriteria (linked via ies:isPartOf). Versioned via ies:successorTo. """@en-gb ; rdfs:subClassOf ies:Asset . marvin:ValidationCriterion a rdfs:Class ; rdfs:label "Validation Criterion"@en-gb ; dcterms:identifier "{AA27A018-E4CC-4A63-BF79-49964915D36E}" ; rdfs:comment """An Asset representing a single formal validation check within a ValidationProfile. Proper part of its profile via ies:isPartOf. Carries a severity level via marvin:criterionSeverity. A criterion's execution-engine kind is its rdf:type, drawn from the marvin:ClassOfValidationCriterionByKind taxonomy (Section H): marvin:SparqlAskCriterion, marvin:SparqlSelectCriterion, marvin:ShaclCriterion, or marvin:PytestCriterion. A SPARQL-ASK or SPARQL-SELECT criterion carries its check inline in marvin:criterionExpression; a SHACL or pytest criterion carries an off-graph reference in marvin:criterionArtefact. The validation runner dispatches on the type. See DD-015 (Amendments 1 & 2). """@en-gb ; ies:powertype marvin:ClassOfValidationCriterion ; rdfs:subClassOf ies:Asset . marvin:ClassOfValidationCriterion a rdfs:Class ; rdfs:label "Class Of Validation Criterion"@en-gb ; dcterms:identifier "{A3741A3B-CA23-4F7A-99E1-B86AAD95020F}" ; rdfs:comment """The powertype of ValidationCriterion. ValidationCriterion is an ies:Asset, so ies:ClassOfAsset is the correct parent in the IES ClassOfElement hierarchy. The marvin:ClassOfValidationCriterionByKind taxonomy (Section H) subclasses this. Added v0.2.13 per DD-015 (Amendment 1). """@en-gb ; rdfs:subClassOf ies:ClassOfAsset . marvin:CriterionResult a rdfs:Class ; rdfs:label "Criterion Result"@en-gb ; dcterms:identifier "{AE5F4CD0-ABED-4779-9019-ED47ABBFDF51}" ; rdfs:comment """An Asset: the immutable record of executing one ValidationCriterion within one ValidationRun. A proper part of its run via ies:isPartOf. Carries marvin:resultOfCriterion (the criterion it realises) and, on failure, marvin:offendingSubject (a bounded sample of the IRIs that tripped the criterion), marvin:offendingSubjectCount (the true total), and marvin:resultMessage. A criterion result's outcome is its rdf:type, drawn from the marvin:ClassOfCriterionResultByOutcome taxonomy (Section H): marvin:PassResult, marvin:FailResult, or marvin:SkippedResult. Not a state-chain entity: a CriterionResult is immutable -- it has no revisions and no ies:BoundingState, and Pattern B does not apply. Typing it by outcome is therefore safe: the outcome is fixed at the moment of the run and never changes. Added v0.2.13 per DD-015 (Amendment 1). """@en-gb ; ies:powertype marvin:ClassOfCriterionResult ; rdfs:subClassOf ies:Asset . marvin:ClassOfCriterionResult a rdfs:Class ; rdfs:label "Class Of Criterion Result"@en-gb ; dcterms:identifier "{6711D63B-AEAF-4BC0-BBF1-A74CA3E22CC6}" ; rdfs:comment """The powertype of CriterionResult. CriterionResult is an ies:Asset, so ies:ClassOfAsset is the correct parent. The marvin:ClassOfCriterionResultByOutcome taxonomy (Section H) subclasses this. Added v0.2.13 per DD-015 (Amendment 1). """@en-gb ; rdfs:subClassOf ies:ClassOfAsset . marvin:UseCase a rdfs:Class ; rdfs:label "Use Case"@en-gb ; dcterms:identifier "{68E1CAA3-3030-43BE-AE6A-9E521544A622}" ; rdfs:comment """A WorkOfDocumentation representing a concrete scenario that motivates or grounds ontology development. May carry an A/B party description. Related to SampleData via marvin:hasSampleData (not ies:isPartOf -- the same data may ground multiple use cases). """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:SampleData a rdfs:Class ; rdfs:label "Sample Data"@en-gb ; dcterms:identifier "{2800EEA1-2A5B-4954-B047-D9BB6CAE22EC}" ; rdfs:comment """A WorkOfDocumentation representing a dataset or data fragment that illustrates or grounds a UseCase. Not a proper part of any single UseCase -- the same SampleData may ground multiple UseCases. """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:Projection a rdfs:Class ; rdfs:label "Projection"@en-gb ; dcterms:identifier "{7DC7C40F-DEBA-4620-BA0D-E6606D234F32}" ; rdfs:comment """An Asset representing a named, reusable consumer view of the Memory Graph. A Projection is a SPARQL CONSTRUCT query stored as a first-class graph node, making views queryable, versioned, and auditable. """@en-gb ; rdfs:subClassOf ies:Asset . marvin:LedgerSection a rdfs:Class ; rdfs:label "Ledger Section"@en-gb ; dcterms:identifier "{6E7F8A9B-0C1D-4E2F-3A4B-5C6D7E8F9A0B}" ; rdfs:comment """A documentation-structural anchor for a section, sub-section, or sub-sub-section of a Marvin ledger (e.g. the worked-example memory-graph-entries.ttl ledger). Instances are minted to provide IRIs for structural cross-references from decision- and state-layer nodes back to specific ledger locations, via marvin:relatedToSection. Bare class at v0.2.11: no IRI template in Section L; no specific subproperty hierarchy beyond rdfs:Class. The worked-example convention mints with bare `we:section-{N}` IRIs (where `{N}` is the dash-separated section number, e.g. `we:section-12-4` for §12.4) per the worked-example- namespacing convention parallel to we:dd-we-g-NNN, we:rej-we-g-NNN-slug, and we:session-gN. The dash represents the dot in the section number (kebab-case discipline; the dot-preserved form `we:section-12.4` would not satisfy kebab-case strictness elsewhere in worked-example IRIs). A future project-level (non-worked-example) ledger would need a Section L IRI template. None is declared at v0.2.11; added when concretely required. Added in v0.2.11 per DD-012 § Phase 2 Q1(c) refinement; consumed by marvin:relatedToSection (Section F). marvin:LedgerSection is documentation-structural rather than decision-substantive — it sits with marvin:UseCase, marvin:SampleData, and marvin:Projection in Section C, not with the decision-bearing classes (DevelopmentDecision, RejectedAlternative, OpenTension). """@en-gb ; rdfs:subClassOf ies:Asset . # ========================================================================== # SECTION D -- Process / event classes # ========================================================================== marvin:DevelopmentSession a rdfs:Class ; rdfs:label "Development Session"@en-gb ; dcterms:identifier "{28E9F8CC-B85C-4968-B975-C729136A73D8}" ; rdfs:comment """An Event representing a working session in the Marvin workflow. Also a prov:Activity; decisions carry prov:wasGeneratedBy links to the session in which they were made. """@en-gb ; rdfs:subClassOf ies:Event, prov:Activity . marvin:DiscoverySession a rdfs:Class ; rdfs:label "Discovery Session"@en-gb ; dcterms:identifier "{96BEC2D1-1D77-4FAA-BCC7-7204EFE2A37A}" ; owl:deprecated true ; rdfs:comment """DEPRECATED (DD-021, schema v0.2.15). Mode is not a whole-life property of a session: a single operationally-continuous session moves through discovery, development, and closure modes. Use marvin:DevelopmentSession with a chain of marvin:DevelopmentSessionState, the discovery stretch typed marvin:DiscoveryMode. Retained, not deleted, so existing issue / PR / doc references to the class name still resolve; no new session instance should be typed with this class. """@en-gb ; rdfs:subClassOf marvin:DevelopmentSession . marvin:DevelopmentWorkSession a rdfs:Class ; rdfs:label "Development Work Session"@en-gb ; dcterms:identifier "{FC15A89F-B8EF-40DF-9BAE-626D05D33811}" ; owl:deprecated true ; rdfs:comment """DEPRECATED (DD-021, schema v0.2.15). Mode is not a whole-life property of a session: a single operationally-continuous session moves through discovery, development, and closure modes. Use marvin:DevelopmentSession with a chain of marvin:DevelopmentSessionState, the development stretch typed marvin:DevelopmentMode. Retained, not deleted, so existing issue / PR / doc references to the class name still resolve; no new session instance should be typed with this class. """@en-gb ; rdfs:subClassOf marvin:DevelopmentSession . marvin:DevelopmentSessionState a rdfs:Class ; rdfs:label "Development Session State"@en-gb ; dcterms:identifier "{50EE59E5-99D0-4526-BBE6-CF4DDB1EF083}" ; rdfs:comment """A temporal state of a marvin:DevelopmentSession, classified by the workflow mode in force during that stretch. Mode -- discovery, development, closure -- holds over a sub-extent of a session, not the whole of it: a session running discovery then development then closure is one DevelopmentSession with three successive DevelopmentSessionStates. An ies:EventState used for a genuine qualitative state, not an "ended"-style pseudo-state -- the session's start and end remain its temporal extent and BoundingStates. Successive mode-states are bounded by ies:BoundingState and linked via ies:after; they are distinct successive states, not revisions (no marvin:revisionNumber, no prov:wasRevisionOf). Mode is applied by typing the state with one of the marvin:ClassOfDevelopmentSessionStateByMode entries (Section H.12); the entered mode-state may carry marvin:triggeredBy to the marvin:Finding that prompted the shift. Phase 1 design is DD-021; host issue #80. """@en-gb ; rdfs:subClassOf ies:EventState . marvin:QASession a rdfs:Class ; rdfs:label "QA Session"@en-gb ; dcterms:identifier "{2B3C4D5E-6F7A-4B2C-9D0E-1F2A3B4C5D6E}" ; rdfs:comment """A DevelopmentSession initiated by a posed DevelopmentQuestion. Produces one or more QARecord compiled documents as output. Sources drawn upon are linked from each QARecord via prov:hadPrimarySource and prov:wasQuotedFrom. """@en-gb ; rdfs:subClassOf marvin:DevelopmentSession . marvin:ReviewEvent a rdfs:Class ; rdfs:label "Review Event"@en-gb ; dcterms:identifier "{A329740E-44F6-4CB7-8B6B-B0D95F1C81B3}" ; rdfs:comment """An Event representing a peer review episode. Peer review is a critical-friend activity throughout the process, not a final gate. """@en-gb ; rdfs:subClassOf ies:Event . marvin:ValidationRun a rdfs:Class ; rdfs:label "Validation Run"@en-gb ; dcterms:identifier "{77ADBD6C-3593-48CB-9702-5A9B929E52B9}" ; rdfs:comment """An Event representing the execution of a ValidationProfile against one or more Assets -- an OntologyModule, or a populated backend. Carries one marvin:CriterionResult per executed criterion, linked via ies:isPartOf. See DD-015. """@en-gb ; rdfs:subClassOf ies:Event . # ========================================================================== # SECTION E -- Agent classes # ========================================================================== marvin:ArtificialAgent a rdfs:Class ; rdfs:label "Artificial Agent"@en-gb ; dcterms:identifier "{9DC2E3F5-46DE-44DC-AD48-5976DC11551A}" ; rdfs:comment """A ResponsibleActor that is an AI system or automated process acting within the Marvin workflow. Each distinct model configuration (model version + system prompt version) is a distinct instance. URI scheme: https://w3id.org/marvin/agent/{model-id}/{system-version} """@en-gb ; rdfs:subClassOf ies:ResponsibleActor . marvin:AgentProfile a rdfs:Class ; rdfs:label "Agent Profile"@en-gb ; dcterms:identifier "{E4769E9C-5A50-4FEB-BA93-FB086163660A}" ; rdfs:comment """A reviewer/agent persona: a reusable remit and reasoning style, independent of the substrate that enacts it. Powertype over ies:ResponsibleActorState -- each AgentProfile instance is itself a class whose members are the ResponsibleActorStates in which some actor (a human ies:Person, or a marvin:ArtificialAgent) enacts that persona. Carried structurally, not via an ies:powertype triple: an AgentProfile is rdfs:subClassOf ies:ClassOfResponsibleActorState and each persona instance is dual-typed (a marvin:AgentProfile ; rdfs:subClassOf ies:ResponsibleActorState), following the H.3 ClassOfResponsibleActorStateByURIScheme idiom. Distinct from marvin:ArtificialAgent, which is the AI actor itself: an AgentProfile is the remit, not the substrate; the two are orthogonal and neither deprecates the other. Phase 1 design is DD-017; host issue #78. """@en-gb ; rdfs:subClassOf ies:ClassOfResponsibleActorState . marvin:AgentRole a rdfs:Class ; rdfs:label "Agent Role"@en-gb ; dcterms:identifier "{13E7FB90-CAB2-4A14-B153-EECDAD0C3763}" ; rdfs:comment """The participation of an actor enacting an AgentProfile persona in a workflow event -- e.g. Ellis on a particular ReviewEvent panel. An ies:ActiveEventParticipant: panel participation is active. Each AgentRole is also a ies:ResponsibleActorState (ies:EventParticipant rdfs:subClassOf ies:State, its participant a ies:ResponsibleActor) and a member of its persona's marvin:AgentProfile class. Linked to the event via ies:isParticipantIn and to the enacting actor via ies:isParticipationOf. Alpha instantiates AgentRole only against marvin:ReviewEvent; the class itself is not event-kind-scoped. marvin:AgentRole is the first ies:EventParticipant subclass in marvin-schema.ttl. Phase 1 design is DD-017; host issue #78. """@en-gb ; rdfs:subClassOf ies:ActiveEventParticipant . marvin:promptDefinition a owl:DatatypeProperty ; rdfs:label "prompt definition"@en-gb ; dcterms:identifier "{6F65F00B-2910-4032-9F78-4F071B7DCB81}" ; rdfs:comment """Repo-relative path to the authoritative definition file for a marvin:AgentProfile persona, under the top-level personas/ directory. The personas/ directory is authoritative; CLAUDE.md's persona section is regenerated from it. See DD-017. """@en-gb ; rdfs:domain marvin:AgentProfile ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . # ========================================================================== # SECTION F -- Object properties # ========================================================================== marvin:concernsArtefact a owl:ObjectProperty ; rdfs:label "concerns Artefact"@en-gb ; dcterms:identifier "{647E2E81-2DEA-47BB-97DD-0EC6CBE79070}" ; rdfs:comment """Links a decision-layer node to the existence-layer artefact it is about. Primary cross-layer link; never runs in reverse. """@en-gb ; rdfs:domain ies:Assessment ; rdfs:range ies:Asset ; rdfs:subPropertyOf ies:relationship . marvin:rejectedInFavourOf a owl:ObjectProperty ; rdfs:label "rejected In Favour Of"@en-gb ; dcterms:identifier "{27882B5F-385D-4115-B5CA-0E3D57763B60}" ; rdfs:comment "Links a RejectedAlternative to the DevelopmentDecision adopted instead."@en-gb ; rdfs:domain marvin:RejectedAlternative ; rdfs:range marvin:DevelopmentDecision ; rdfs:subPropertyOf ies:relationship . marvin:tensionBetween a owl:ObjectProperty ; rdfs:label "tension Between"@en-gb ; dcterms:identifier "{3E232E72-E47E-4F7B-81E9-EA6FB2329D07}" ; rdfs:comment """Links an OpenTension to the Principles that are in tension. Symmetric in intent; directionality is arbitrary. """@en-gb ; rdfs:domain marvin:OpenTension ; rdfs:range marvin:Principle ; rdfs:subPropertyOf ies:relationship . marvin:groundedInPrinciple a owl:ObjectProperty ; rdfs:label "grounded In Principle"@en-gb ; dcterms:identifier "{82C29871-AE5F-4C34-ADCD-13B82FB41A73}" ; rdfs:comment "Links a DevelopmentDecision to the Principle(s) that justify it."@en-gb ; rdfs:domain marvin:DevelopmentDecision ; rdfs:range marvin:Principle ; rdfs:subPropertyOf ies:relationship . marvin:groundedIn a owl:ObjectProperty ; rdfs:label "grounded In"@en-gb ; dcterms:identifier "{3C4D5E6F-7A8B-4C3D-0E1F-2A3B4C5D6E7F}" ; rdfs:comment """Links a DevelopmentDecision to the evidence or artefact that grounds it — e.g. a QARecord, a ValidationRun, or a resolved OpenTension. A decision may be grounded in multiple artefacts. Direction: DevelopmentDecision -> evidence (forward from decision to its evidential basis). Preferred over an inverse property (e.g. marvin:supportsDecision) because the natural query is 'what grounds this decision?' and a decision may be grounded in heterogeneous evidence types without requiring a per-type property. See DD-004. """@en-gb ; rdfs:domain marvin:DevelopmentDecision ; rdfs:range ies:Thing ; rdfs:subPropertyOf ies:relationship . marvin:satisfiesCQ a owl:ObjectProperty ; rdfs:label "satisfies CQ"@en-gb ; dcterms:identifier "{EB6EB7E5-1321-4A83-A024-571BED630152}" ; rdfs:comment "Links an OntologyModule (or other artefact) to a CompetencyQuestion it satisfies."@en-gb ; rdfs:domain ies:Asset ; rdfs:range marvin:CompetencyQuestion ; rdfs:subPropertyOf ies:relationship . marvin:isSatisfiedBy a owl:ObjectProperty ; rdfs:label "is Satisfied By"@en-gb ; dcterms:identifier "{6F7A8B9C-1D2E-4F3A-C5D6-7E8F9A0B1C2D}" ; rdfs:comment """Links a CompetencyQuestion to the ValidationRun that demonstrates it is satisfied. Direction: CompetencyQuestion -> ValidationRun (issue -> resolution, forward in time). Consistent with the resolution-direction convention established in DD-004. A CompetencyQuestion is satisfied when the associated SPARQL query (marvin:cqSparql) returns expected results against conforming data as part of the linked ValidationRun. """@en-gb ; rdfs:domain marvin:CompetencyQuestion ; rdfs:range marvin:ValidationRun ; rdfs:subPropertyOf ies:relationship . marvin:motivatedBy a owl:ObjectProperty ; rdfs:label "motivated By"@en-gb ; dcterms:identifier "{BC2EC419-0438-48FB-87EE-BC744A948929}" ; rdfs:comment "Links an existence-layer artefact to the UseCase that motivated it."@en-gb ; rdfs:domain ies:Asset ; rdfs:range marvin:UseCase ; rdfs:subPropertyOf ies:relationship . marvin:hasSampleData a owl:ObjectProperty ; rdfs:label "has Sample Data"@en-gb ; dcterms:identifier "{3050F630-1F94-40CF-85C6-8D5A7944D88F}" ; rdfs:comment """Relates a UseCase to SampleData that illustrates or grounds it. Not a parthood relationship -- the same SampleData may ground multiple UseCases. """@en-gb ; rdfs:domain marvin:UseCase ; rdfs:range marvin:SampleData ; rdfs:subPropertyOf ies:relationship . marvin:appliesProfile a owl:ObjectProperty ; rdfs:label "applies Profile"@en-gb ; dcterms:identifier "{7003D73F-1F73-4A95-914D-9D27D57B95F7}" ; rdfs:comment "Links a ValidationRun to the ValidationProfile it executed."@en-gb ; rdfs:domain marvin:ValidationRun ; rdfs:range marvin:ValidationProfile ; rdfs:subPropertyOf ies:relationship . marvin:validates a owl:ObjectProperty ; rdfs:label "validates"@en-gb ; dcterms:identifier "{4413F3B0-EA31-47A1-920A-34B445E0E32D}" ; rdfs:comment "Links a ValidationRun to the artefact (typically OntologyModule) that was validated."@en-gb ; rdfs:domain marvin:ValidationRun ; rdfs:range ies:Asset ; rdfs:subPropertyOf ies:relationship . marvin:criterionSeverity a owl:ObjectProperty ; rdfs:label "criterion severity"@en-gb ; dcterms:identifier "{B284E18F-B6EE-49D9-897D-8B59F12DEEBB}" ; rdfs:comment """The severity level of a ValidationCriterion, drawn from the SHACL severity vocabulary: sh:Violation, sh:Warning, or sh:Info. """@en-gb ; rdfs:domain marvin:ValidationCriterion ; rdfs:range sh:Severity ; rdfs:subPropertyOf ies:relationship . marvin:resultOfCriterion a owl:ObjectProperty ; rdfs:label "result of criterion"@en-gb ; dcterms:identifier "{3EC00915-4BF2-45A4-B4E6-C6B4B2633E1D}" ; rdfs:comment """Links a marvin:CriterionResult to the marvin:ValidationCriterion it realises -- the criterion whose execution the result records. Added v0.2.13 per DD-015. """@en-gb ; rdfs:domain marvin:CriterionResult ; rdfs:range marvin:ValidationCriterion ; rdfs:subPropertyOf ies:relationship . marvin:offendingSubject a owl:ObjectProperty ; rdfs:label "offending subject"@en-gb ; dcterms:identifier "{251BE2A7-861E-4C52-BE1F-F5FACA1662E7}" ; rdfs:comment """Links a failed marvin:CriterionResult (one typed marvin:FailResult) to a subject IRI that tripped its criterion. A bounded sample only: the validation runner caps the number of marvin:offendingSubject triples written and records the true total in marvin:offendingSubjectCount, so the run graph does not grow with the size of a failure. Added v0.2.13 per DD-015 Consequence 4. """@en-gb ; rdfs:domain marvin:CriterionResult ; rdfs:range ies:Thing ; rdfs:subPropertyOf ies:relationship . marvin:answersQuestion a owl:ObjectProperty ; rdfs:label "answers Question"@en-gb ; dcterms:identifier "{4D5E6F7A-8B9C-4D4E-1F2A-3B4C5D6E7F8A}" ; rdfs:comment """Links a DevelopmentQuestion to the QARecord that answers it. Direction: DevelopmentQuestion -> QARecord (issue -> resolution, forward in time). Consistent with ies:successorTo idiom. See DD-004. A DevelopmentQuestion may be answered by more than one QARecord (e.g. initial answer followed by a revision). In that case, successive QARecords are linked via prov:wasRevisionOf. """@en-gb ; skos:note """The declared range is marvin:QARecord, which is simultaneously a taxonomy enumeration instance (of ClassOfCompiledDocumentStateByCompileType) and a class (of CompiledDocumentState individuals). This dual role is correct per the IES powertype pattern: range individuals at the data level are CompiledDocumentState instances typed 'a marvin:QARecord', not the marvin:QARecord class resource itself. """@en-gb ; rdfs:domain marvin:DevelopmentQuestion ; rdfs:range marvin:QARecord ; rdfs:subPropertyOf ies:relationship . marvin:referencesDocument a owl:ObjectProperty ; rdfs:label "references Document"@en-gb ; dcterms:identifier "{5E6F7A8B-9C0D-4E5F-2A3B-4C5D6E7F8A9B}" ; rdfs:comment """Asserts a navigational or inline reference between two marvin:CompiledDocumentState nodes — typically index-entry, citation, or QA-source links between compile-pipeline outputs. Operates at the state level. The property links the specific temporal part (the rev-{n} state) that contains or makes the reference to the specific temporal part being referenced, not the whole-life marvin:CompiledDocument aggregate. This matches the 4D extensional treatment of compiled documents used elsewhere in the compile pipeline. Typical uses (state-level): - IndexDocument-state -> ConceptArticle-state (navigational index entry) - ConceptArticle-state -> Summary-state (inline citation) - QARecord-state -> Summary-state or ConceptArticle-state (inline citation) Relation to other compile-pipeline edges. The schema's two other state-targeting object properties on compile-pipeline nodes — marvin:shortCircuitedAgainstState (this section) and prov:wasDerivedFrom under the convention pinned by DD-WE-G-004 — also operate at the state level; the consistency is intentional. marvin:referencesDocument is intentionally narrower than prov:wasDerivedFrom: a navigational or inline reference is a stronger claim than derivation. The compile pipeline currently writes both edges at the same targets where appropriate (see marvin/pipeline/compile/index.py); a future stage that asserts derivation without inline reference, or inline reference without derivation, is coherent and the schema does not preclude it. Rationale for the state-level reading. Under the pre-fix document-level reading, marvin:referencesDocument and prov:wasDerivedFrom — pointing at the same target tuple per the Index stage's pinned design decision — would have contradicted each other on the level at which the references operated. Aligning marvin:referencesDocument with the state-level reading already adopted for prov:wasDerivedFrom removes the contradiction. See DD-WE-G-005 (forthcoming, in the compile-pipeline-powertype-pattern worked example) for the elevation rationale that pairs with this schema fix, and DD-WE-G-004 for the parallel state-level decision on prov:wasDerivedFrom. Historical note. Earlier versions of this comment described the property as operating between ies:IndividualDocument (whole-life marvin:CompiledDocument) instances. PR #58 (Issue #29) implemented the property at the state level — the temporally-precise reading consistent with the 4D extensional treatment of compiled documents — without an accompanying schema update. #84 Stage 4 design preparation surfaced the divergence; Issue #91 aligned the schema with the implementation. """@en-gb ; rdfs:domain marvin:CompiledDocumentState ; rdfs:range marvin:CompiledDocumentState ; rdfs:subPropertyOf ies:relationship . marvin:shortCircuitedAgainstFile a owl:ObjectProperty ; rdfs:label "short-circuited against file"@en-gb ; dcterms:identifier "{1D8F2A7B-6E9C-4A5D-B3C4-7E0F1A2B3C4D}" ; rdfs:comment """Links a marvin:ShortCircuitDecision to the marvin:CorpusFileState whose marvin:fileChecksum was evaluated during the short-circuit check. This is the temporal part of the source the pipeline found unchanged relative to the most recent CompiledDocumentState; the whole-life marvin:CorpusFile is reachable from it via ies:isStateOf. Range scope. v0.2.9 retypes the range from marvin:CorpusFile to marvin:CorpusFileState, paired with DD-010's state-chain introduction. See DD-010 (Q3 resolution) and the schema's Section J / Section L additions for marvin:CorpusFileState. Pre-v0.2.9 short-circuit events targeted whole-life marvin:CorpusFile; post-v0.2.9 events target the latest marvin:CorpusFileState found to match the on-disk source. The worked-example ABox migration in the [#117](https://github.com/aigora-de/marvin/issues/117) Phase 2 PR Commit 2 mints rev-1 CorpusFileState instances for all five [#30](https://github.com/aigora-de/marvin/issues/30) CorpusFiles; pre-existing short-circuit events (none in the worked example as of [#117](https://github.com/aigora-de/marvin/issues/117) Phase 2 entry) would migrate by retargeting at their latest CorpusFileState. Complementary to prov:hadPrimarySource: the latter is reserved for provenance edges on compiled document states (which carry their source at compile time), whereas this property on the short-circuit event records "the source we were going to compile from but did not". Using a dedicated property avoids overloading prov:hadPrimarySource with the "source that would have been used if we had written" semantics. See Issue #29 and DD-007 Consequences "Short-circuit logging" for the full original rationale, and DD-010 for the v0.2.9 range update. """@en-gb ; rdfs:domain marvin:ShortCircuitDecision ; rdfs:range marvin:CorpusFileState ; rdfs:subPropertyOf ies:relationship . marvin:shortCircuitedAgainstState a owl:ObjectProperty ; rdfs:label "short-circuited against state"@en-gb ; dcterms:identifier "{2E9F3B8C-7F0D-4B6E-C4D5-8F1A2B3C4D5E}" ; rdfs:comment """Links a marvin:ShortCircuitDecision to the most recent marvin:CompiledDocumentState whose marvin:sourceChecksumAtCompile matched the current checksum of the source file. This is the state that was found to already represent the current source, making a new compile run unnecessary. Via this link, the checksum value that drove the short-circuit is recoverable as ?ev marvin:shortCircuitedAgainstState/marvin:sourceChecksumAtCompile without duplicating the literal on the event node. Revision number, compile type, and compile instant of the reused state are similarly recoverable via its existing properties. """@en-gb ; rdfs:domain marvin:ShortCircuitDecision ; rdfs:range marvin:CompiledDocumentState ; rdfs:subPropertyOf ies:relationship . marvin:replicatedFrom a owl:ObjectProperty ; rdfs:label "replicated from"@en-gb ; dcterms:identifier "{8E7D5C3B-9A4F-4F1D-A2C8-6B5E0D9F1A2B}" ; rdfs:comment """Asserts that a marvin:CorpusFile is a verbatim or near-verbatim copy of an upstream ies:IndividualDocument. The upstream-anchor is typically a non-tracked structural placeholder for the source of replication: it is minted by the indexer pipeline (or editorially) at the time the corpus copy is registered, and is not subject to ongoing pipeline tracking. Semantics: replication is a non-temporal identity statement between whole-life entities. The corpus copy and the upstream copy are both ies:aCopyOf the same ies:WorkOfDocumentation; marvin:replicatedFrom records which upstream copy specifically the corpus file was replicated from. Distinct from prov:wasDerivedFrom (which records temporal-extent derivation activity) and from prov:hadPrimarySource (which records the primary input to a temporal-extent derivation). The upstream-anchor is intentionally non-tracked: it carries no marvin:fileChecksum, no marvin:ingestTimestamp, no state chain, and is not a marvin:CorpusFile. Its role is structural (provide an IRI for marvin:replicatedFrom to target) and attributional (carry rights/copyright triples that the corpus copy inherits from the upstream). Provisional v0.2.9 status. The predicate is declared in v0.2.9 and exercised by the [#30](https://github.com/aigora-de/marvin/issues/30) worked-example ABox migration (two replicated CorpusFiles: corpus/extending-ies.md and corpus/ies-common.ttl, each pointing at an upstream-anchor minted under the new template in Section L). Indexer-pipeline minting of these edges is scoped to [#123](https://github.com/aigora-de/marvin/issues/123) rather than landing in [#117](https://github.com/aigora-de/marvin/issues/117) Phase 2. See DD-011 for the full design rationale. """@en-gb ; rdfs:domain marvin:CorpusFile ; rdfs:range ies:IndividualDocument ; rdfs:subPropertyOf ies:relationship . marvin:relatedToSection a owl:ObjectProperty ; rdfs:label "related to section"@en-gb ; dcterms:identifier "{7F8A9B0C-1D2E-4F3A-4B5C-6D7E8F9A0B1C}" ; rdfs:comment """Links a marvin:OpenTensionState to a marvin:LedgerSection — the section of the worked-example or project-level ledger in which the OpenTension's whole-life surfacing, narrowing event, resolution event, or related material is recorded. Provides typed structural cross-references that replace the prose-only `marvin:relatedToSection §N.M` references in Section 21's rdfs:comment literals (per #94 Phase 2 Q1(c) refinement). The predicate is multi-valued by intent: a single OpenTensionState may relate to multiple ledger sections (e.g. surfacing section + narrowing-event section + closure-synthesis section); a single LedgerSection may likewise be related to from multiple OpenTensionStates. Domain scope. v0.2.11 declares the property's domain as marvin:OpenTensionState alone — the only consumer at this version. The domain extends by union under the precedent established by marvin:revisionNumber (DD-010 / DD-012) and marvin:fileChecksum (DD-010) when future consumers (RejectedAlternatives, DevelopmentDecisions, ValidationRuns, etc.) surface a need for typed structural cross-references. Range. marvin:LedgerSection (Section C). The range is deliberately narrow: relatedToSection is for ledger- structural references, not for general-purpose cross- document linking. Cross-document links (e.g. from an OpenTensionState to a separate stylebook entry or DD document) are not in scope at v0.2.11. Added in v0.2.11 per DD-012 § Phase 2 Q1(c) refinement. Consumed by Section 22 of the worked-example ledger (memory-graph-entries.ttl) for #94 Phase 2 Commit 5 (forthcoming). """@en-gb ; rdfs:domain marvin:OpenTensionState ; rdfs:range marvin:LedgerSection ; rdfs:subPropertyOf ies:relationship . marvin:raisedBy a owl:ObjectProperty ; rdfs:label "raised by"@en-gb ; dcterms:identifier "{24B037E5-FB39-4190-B9D7-24992195CD7C}" ; rdfs:comment """Links a marvin:Finding to the marvin:AgentRole of the reviewer persona that raised it. The AgentRole is the persona's participation in the ReviewEvent the Finding is ies:isPartOf; the persona itself is recovered from the AgentRole's AgentProfile-class type. A sanctioned shortcut -- no ies:Assessor is minted per Finding. See DD-018, DD-017. """@en-gb ; rdfs:domain marvin:Finding ; rdfs:range marvin:AgentRole ; rdfs:subPropertyOf ies:relationship . marvin:supersededBy a owl:ObjectProperty ; rdfs:label "superseded by"@en-gb ; dcterms:identifier "{BE5160F9-EC15-4A51-9EF1-400E784D0AF3}" ; rdfs:comment """Links a marvin:DevelopmentDecision to the later marvin:DevelopmentDecision the deliberation adopted in its place. A deliberative relation, NOT a temporal one -- deliberately not a subproperty of ies:after: it asserts methodological replacement, not clock-time ordering. The superseded decision's adopted-position marvin:DevelopmentDecisionState is closed under DD-005 Pattern B at the same time; whether a decision is still in force is read from that bounding topology (DD-016), not from this property. Optional: a decision abandoned with no successor carries no supersededBy triple. Subject is the superseded (older) decision, object the superseding (newer) one. Distinct from marvin:rejectedInFavourOf, which points from a never-adopted marvin:RejectedAlternative. See DD-019. """@en-gb ; rdfs:domain marvin:DevelopmentDecision ; rdfs:range marvin:DevelopmentDecision ; rdfs:subPropertyOf ies:relationship . marvin:adoptedAs a owl:ObjectProperty ; rdfs:label "adopted as"@en-gb ; dcterms:identifier "{47751106-245F-4633-95FD-9AB802887AC6}" ; rdfs:comment """Links a marvin:Proposal to the marvin:DevelopmentDecision it was adopted as. Its presence marks the Proposal resolved-by-adoption. A Proposal carries marvin:adoptedAs or marvin:rejectedAs, never both; absence of either marks it still open. See DD-020. """@en-gb ; rdfs:domain marvin:Proposal ; rdfs:range marvin:DevelopmentDecision ; rdfs:subPropertyOf ies:relationship . marvin:rejectedAs a owl:ObjectProperty ; rdfs:label "rejected as"@en-gb ; dcterms:identifier "{F7DEDAD4-F39E-465B-B440-4BBB7484D11F}" ; rdfs:comment """Links a marvin:Proposal to the marvin:RejectedAlternative it was closed as. Its presence marks the Proposal resolved-by-rejection. A Proposal carries marvin:adoptedAs or marvin:rejectedAs, never both; absence of either marks it still open. See DD-020. """@en-gb ; rdfs:domain marvin:Proposal ; rdfs:range marvin:RejectedAlternative ; rdfs:subPropertyOf ies:relationship . marvin:triggeredBy a owl:ObjectProperty ; rdfs:label "triggered by"@en-gb ; dcterms:identifier "{E7CF1EF8-6559-467F-8708-31ECA2985122}" ; rdfs:comment """Links a marvin:DevelopmentSessionState to the marvin:Finding whose surfacing prompted the shift into that mode -- the trigger attaches to the entered mode-state, not to a transition node (no marvin:ModeTransition class is minted; a transition is the ies:BoundingState between two adjacent mode-states). See DD-021, DD-018. """@en-gb ; rdfs:domain marvin:DevelopmentSessionState ; rdfs:range marvin:Finding ; rdfs:subPropertyOf ies:relationship . marvin:projectionQuery a owl:DatatypeProperty ; rdfs:label "projection query"@en-gb ; dcterms:identifier "{3A4DA312-C450-44B1-9E8E-10CE059E79C3}" ; rdfs:comment """The SPARQL CONSTRUCT query that materialises a consumer view from the full Memory Graph. """@en-gb ; rdfs:domain marvin:Projection ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:projectionConsumer a owl:DatatypeProperty ; rdfs:label "projection consumer"@en-gb ; dcterms:identifier "{DF4DD5B3-2DA6-4FEB-94F8-70ED35F2F06F}" ; rdfs:comment """Identifies the intended consumer role for this Projection. Values: 'ontologist' | 'domain-expert' | 'newcomer' | 'reviewer'. """@en-gb ; rdfs:domain marvin:Projection ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . # ========================================================================== # SECTION G -- Datatype properties # ========================================================================== marvin:cqNarrative a owl:DatatypeProperty ; rdfs:label "CQ narrative"@en-gb ; dcterms:identifier "{9492B11B-C9FA-4EC5-9A53-B8B4B0310088}" ; rdfs:comment "The natural language statement of a CompetencyQuestion."@en-gb ; rdfs:domain marvin:CompetencyQuestion ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:cqSparql a owl:DatatypeProperty ; rdfs:label "CQ SPARQL"@en-gb ; dcterms:identifier "{BEFAAE5C-6EBC-44BB-800E-78F7EE4567BA}" ; rdfs:comment "The SPARQL SELECT or ASK query that formalises a CompetencyQuestion."@en-gb ; rdfs:domain marvin:CompetencyQuestion ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:criterionExpression a owl:DatatypeProperty ; rdfs:label "criterion expression"@en-gb ; dcterms:identifier "{F26A7C86-2067-4597-9909-0C9A28AA9873}" ; rdfs:comment """The SPARQL query string of a marvin:SparqlAskCriterion (an ASK) or a marvin:SparqlSelectCriterion (a SELECT). A SHACL or pytest criterion carries an off-graph reference in marvin:criterionArtefact instead; exactly one of marvin:criterionExpression / marvin:criterionArtefact is present on a criterion, determined by its rdf:type within the marvin:ClassOfValidationCriterionByKind taxonomy. See DD-015 (Amendments 1 & 2). """@en-gb ; rdfs:domain marvin:ValidationCriterion ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:criterionArtefact a owl:DatatypeProperty ; rdfs:label "criterion artefact"@en-gb ; dcterms:identifier "{7F7D8EAC-1131-4647-8EF3-B82BFC8BB1EE}" ; rdfs:comment """A reference to the off-graph artefact realising a non-SPARQL-ASK marvin:ValidationCriterion: a repository-relative path to a validation/shacl/*.shapes.ttl file (for a marvin:ShaclCriterion), or a pytest node id (for a marvin:PytestCriterion). Exactly one of marvin:criterionArtefact / marvin:criterionExpression is present on a criterion. See DD-015 (Amendment 1). """@en-gb ; rdfs:domain marvin:ValidationCriterion ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:resultMessage a owl:DatatypeProperty ; rdfs:label "result message"@en-gb ; dcterms:identifier "{726146E9-166E-4312-BB00-99801F0BEFF1}" ; rdfs:comment """A short operator-facing message on a marvin:CriterionResult. For a SHACL-criterion result it carries the adapted pyshacl sh:resultMessage. Added v0.2.13 per DD-015. """@en-gb ; rdfs:domain marvin:CriterionResult ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:offendingSubjectCount a owl:DatatypeProperty ; rdfs:label "offending subject count"@en-gb ; dcterms:identifier "{D5ADA49C-09A4-4367-80A1-57864DCECDEC}" ; rdfs:comment """The true total number of subjects that tripped a failed criterion. The marvin:offendingSubject triples on the bearing marvin:CriterionResult carry only a bounded sample; this literal carries the full count. Added v0.2.13 per DD-015 Consequence 4. """@en-gb ; rdfs:domain marvin:CriterionResult ; rdfs:range xsd:nonNegativeInteger ; rdfs:subPropertyOf ies:attribute . marvin:sourceUri a owl:DatatypeProperty ; rdfs:label "source URI"@en-gb ; dcterms:identifier "{1438E433-ECF9-4159-AD48-FA151E806DE0}" ; rdfs:comment "The URI of the ontology entity that an existence-layer node mirrors. Used by the sync pipeline."@en-gb ; rdfs:domain ies:Asset ; rdfs:range xsd:anyURI ; rdfs:subPropertyOf ies:attribute . marvin:revisionNumber a owl:DatatypeProperty ; rdfs:label "revision number"@en-gb ; dcterms:identifier "{7F8A9B0C-1D2E-4F6A-B7C8-9D0E1F2A3B4C}" ; rdfs:comment """The 1-indexed revision number of a state-chain node within its (work-slug, ...) scope. Computed at mint time as 1 + MAX(existing n) or 1 if none. This literal duplicates the {n} variable substituted into the Section L IRI template for the bearing class. The duplication is deliberate: the literal exists so that SPARQL aggregates (MAX, ORDER BY) can operate on revision number directly, without parsing the IRI path. Pipeline code MUST write the same value to both the literal and the IRI, derived from the same computed value in a single mint call; CI enforces agreement. Domain scope. v0.2.9 extended the property's domain from marvin:CompiledDocumentState alone to a union of marvin:CompiledDocumentState and marvin:CorpusFileState, paired with DD-010's introduction of the indexer-layer state-chain. v0.2.11 extends the union further to include marvin:OpenTensionState, paired with DD-012's introduction of the OpenTension state-chain. The same read-before-mint and IRI-literal-agreement disciplines apply on every bearing class. The original foresight in earlier versions of this comment — \"Other pipeline-written state node types whose templates also carry a {n} variable… may adopt this property in future releases if and when SPARQL aggregation on their revision numbers becomes a concrete need\" — is the precedent under which marvin:CorpusFileState (v0.2.9) and marvin:OpenTensionState (v0.2.11) now carry the property. See Issue #29 (compile pipeline implementation) for the original design discussion and the `{n}` read-before-mint serialisation contract, DD-010 for the v0.2.9 domain extension, and DD-012 for the v0.2.11 extension. """@en-gb ; rdfs:domain [ a owl:Class ; owl:unionOf ( marvin:CompiledDocumentState marvin:CorpusFileState marvin:OpenTensionState ) ] ; rdfs:range xsd:positiveInteger ; rdfs:subPropertyOf ies:attribute . marvin:iriTemplate a owl:DatatypeProperty ; rdfs:label "IRI template"@en-gb ; dcterms:identifier "{E7A8F9B1-C2D3-4E5F-A6B7-C8D9E0F1A2B3}" ; rdfs:comment """The deterministic IRI template used by Marvin pipelines when minting instances of a given class. The template is a string containing literal path segments and {curly-brace} variables; pipeline code substitutes variables with values from the node's logical-identity tuple at mint time. Templates are transparent composites of logical inputs, not content hashes. See DD-007 for the full scheme, including the rejected alternatives and the per-node-type templates currently in force (declared in Section L). The domain is rdfs:Class rather than a Marvin-specific class because templates may be declared for Marvin-defined classes (e.g. marvin:CompiledDocumentState) and for externally-owned classes used by Marvin pipelines (e.g. ies:BoundingState, ies:ParticularPeriod), following the 'local assertion on externally-owned class' precedent already used in Section K for ies:Thing rdfs:subClassOf prov:Entity. """@en-gb ; rdfs:domain rdfs:Class ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:proposalSketch a owl:DatatypeProperty ; rdfs:label "proposal sketch"@en-gb ; dcterms:identifier "{AE1CCE2F-DAC8-4BA1-9961-9152EFA8D6C5}" ; rdfs:comment """Repo-relative path to where a marvin:Proposal's candidate Turtle shape is written up. A pointer, not an inline literal -- an inline Turtle blob would be opaque to SPARQL and unreadable in tooling. The candidate's rationale and tradeoffs go in the Proposal's rdfs:comment. See DD-020. """@en-gb ; rdfs:domain marvin:Proposal ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . # ========================================================================== # SECTION H -- Controlled vocabulary taxonomies # ========================================================================== # -------------------------------------------------------------------------- # H.1 ClassOfOntologyArtefactStateBySyncStatus # -------------------------------------------------------------------------- marvin:ClassOfOntologyArtefactStateBySyncStatus a rdfs:Class ; rdfs:label "Class of Ontology Artefact State by Sync Status"@en-gb ; dcterms:identifier "{75D5AE0B-084B-44E8-AD6F-9729165F26AF}" ; rdfs:comment """Controlled vocabulary classifying existence-layer OntologyArtefact nodes by their sync pipeline status. Each entry types a marvin:OntologyArtefactState individual linked to the artefact via ies:isStateOf, enabling point-in-time status queries. The values here are positive departures from the default "currently present in source" condition. That default condition is not a value in this taxonomy -- it is represented temporally, by the absence of a closing ies:BoundingState on the state node. In a 4D extensional ontology, "current" is not a flag; it is the temporal topology of the state's bounding pattern (an opening BoundingState with no closing one). Asserting it as an rdf:type would be a 3D-ist leak, and would go stale the moment the state is superseded. See docs/decisions/DD-005-ies-native-artefact-history-pattern.md. Membership is closed: adding a value requires a governance decision. """@en-gb ; rdfs:subClassOf marvin:ClassOfOntologyArtefactState . marvin:SyncStatusAbsent a marvin:ClassOfOntologyArtefactStateBySyncStatus ; rdfs:label "Sync Status: Absent"@en-gb ; dcterms:identifier "{ABB7852D-3B98-4267-B163-29FAE4DD16C3}" ; rdfs:comment "The artefact was in a prior sync but is no longer in the source. Node retained, not deleted."@en-gb ; rdfs:subClassOf marvin:OntologyArtefactState . marvin:SyncStatusMigrated a marvin:ClassOfOntologyArtefactStateBySyncStatus ; rdfs:label "Sync Status: Migrated"@en-gb ; dcterms:identifier "{4E68F44F-D608-48FA-9E91-A012B474AF4A}" ; rdfs:comment "Superseded by a node in a later IES version. ies:successorTo links the new node to this one."@en-gb ; rdfs:subClassOf marvin:OntologyArtefactState . # -------------------------------------------------------------------------- # H.2 ClassOfOntologyArtefactStateByIESVersion # -------------------------------------------------------------------------- marvin:ClassOfOntologyArtefactStateByIESVersion a rdfs:Class ; rdfs:label "Class of Ontology Artefact State by IES Version"@en-gb ; dcterms:identifier "{C02D1A53-1E72-40CD-8E50-94B3D24505B6}" ; rdfs:comment """Controlled vocabulary of IES versions against which OntologyArtefact nodes are developed. Each entry types an OntologyArtefactState individual to record which IES version the artefact targets during that state, enabling version migration tracking. Generalised from OntologyModule to all OntologyArtefact types. Membership is closed per IES release cycle. """@en-gb ; rdfs:subClassOf marvin:ClassOfOntologyArtefactState . marvin:IESVersionV5 a marvin:ClassOfOntologyArtefactStateByIESVersion ; rdfs:label "IES v5"@en-gb ; dcterms:identifier "{C6FC418C-A274-4DE1-8F70-BF9801874564}" ; rdfs:comment "IES Common v5.x (ies-common.ttl). Namespace: http://informationexchangestandard.org/ont/ies/common/"@en-gb ; rdfs:subClassOf marvin:OntologyArtefactState . marvin:IESVersionV6 a marvin:ClassOfOntologyArtefactStateByIESVersion ; rdfs:label "IES v6"@en-gb ; dcterms:identifier "{809B736A-5BFA-46A4-A0BF-D3AFCDFF0F60}" ; rdfs:comment "IES v6 (ies-top.ttl + ies-core.ttl). Added in anticipation of v6 migration; not yet active."@en-gb ; rdfs:subClassOf marvin:OntologyArtefactState . # -------------------------------------------------------------------------- # H.3 ClassOfResponsibleActorStateByURIScheme # -------------------------------------------------------------------------- marvin:ClassOfResponsibleActorStateByURIScheme a rdfs:Class ; rdfs:label "Class of Responsible Actor State by URI Scheme"@en-gb ; dcterms:identifier "{02C8D252-098C-464E-8FB2-3AE63246018C}" ; rdfs:comment """Controlled vocabulary of URI schemes used to identify agents in the Marvin memory graph. Each entry types a ResponsibleActorState individual linked to the agent via ies:isStateOf, recording the URI scheme applicable during that period. Classifies states (not whole-life actors) so that URI scheme changes can be tracked temporally. Membership is closed. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:URISchemeGitHubHandle a marvin:ClassOfResponsibleActorStateByURIScheme ; rdfs:label "URI Scheme: GitHub Handle"@en-gb ; dcterms:identifier "{906D6CB6-859F-4E53-B980-952733903BFA}" ; rdfs:comment "URI scheme for human contributors: https://github.com/{handle}"@en-gb ; rdfs:subClassOf ies:ResponsibleActorState . marvin:URISchemeMarvinArtificialAgent a marvin:ClassOfResponsibleActorStateByURIScheme ; rdfs:label "URI Scheme: Marvin Artificial Agent"@en-gb ; dcterms:identifier "{7187D533-A95D-45A6-BC84-1340A3228068}" ; rdfs:comment "URI scheme for AI agents: https://w3id.org/marvin/agent/{model-id}/{system-version}"@en-gb ; rdfs:subClassOf ies:ResponsibleActorState . # -------------------------------------------------------------------------- # H.4 ClassOfDevelopmentDecisionStateByABStatus # -------------------------------------------------------------------------- marvin:ClassOfDevelopmentDecisionStateByABStatus a rdfs:Class ; rdfs:label "Class of Development Decision State by AB Party Status"@en-gb ; dcterms:identifier "{EE92B98D-BCBA-452F-8178-220691E9F6A8}" ; rdfs:comment """Controlled vocabulary for the A/B party grounding status of a DevelopmentDecision at a point in time. The A/B party principle requires a concrete party A (information provider) and party B (receiver) before commencing development. Classifies marvin:DevelopmentDecisionState (not the whole-life DevelopmentDecision) because AB grounding is a property of the epistemic context, not of the decision content. A change in AB status creates a new state of the same decision linked via ies:after; the pipeline is responsible for asserting ies:after between successive states. Orthogonal to ClassOfDevelopmentDecisionStateByInfoCompleteness: a state may simultaneously carry both classifiers. Membership is closed. """@en-gb ; rdfs:subClassOf marvin:ClassOfDevelopmentDecisionState . marvin:ABStatusSatisfied a marvin:ClassOfDevelopmentDecisionStateByABStatus ; rdfs:label "AB Status: Satisfied"@en-gb ; dcterms:identifier "{31614208-DAB4-472B-AC9C-1C4BE8E60B01}" ; rdfs:comment "Both party A (information provider) and party B (receiver) are identified."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . marvin:ABStatusPartial a marvin:ClassOfDevelopmentDecisionStateByABStatus ; rdfs:label "AB Status: Partial"@en-gb ; dcterms:identifier "{C633E6E6-AFA9-432F-A67E-6F527182380F}" ; rdfs:comment "One party is identified but not both, or both are identified loosely."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . marvin:ABStatusSpeculative a marvin:ClassOfDevelopmentDecisionStateByABStatus ; rdfs:label "AB Status: Speculative"@en-gb ; dcterms:identifier "{27E52B16-AA2F-437B-ABF6-05821E1C6A16}" ; rdfs:comment "No concrete A/B grounding. Flagged for review; speculative development should be minimised."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . # -------------------------------------------------------------------------- # H.5 ClassOfDevelopmentDecisionStateByInfoCompleteness # -------------------------------------------------------------------------- marvin:ClassOfDevelopmentDecisionStateByInfoCompleteness a rdfs:Class ; rdfs:label "Class of Development Decision State by Information Completeness"@en-gb ; dcterms:identifier "{086BC2C4-32A4-413C-8A9C-8D754B3316DE}" ; rdfs:comment """Controlled vocabulary for the self-assessed completeness of information at the time a DevelopmentDecision state was recorded. Classifies marvin:DevelopmentDecisionState (not the whole-life DevelopmentDecision) because information completeness describes the epistemic context, not the decision content. A change in completeness assessment creates a new state of the same decision linked via ies:after; the pipeline is responsible for asserting ies:after between successive states. Orthogonal to ClassOfDevelopmentDecisionStateByABStatus: a state may simultaneously carry both classifiers. Membership is closed. """@en-gb ; rdfs:subClassOf marvin:ClassOfDevelopmentDecisionState . marvin:InfoCompletenessFull a marvin:ClassOfDevelopmentDecisionStateByInfoCompleteness ; rdfs:label "Info Completeness: Full"@en-gb ; dcterms:identifier "{4FF41432-2221-41F7-85BB-7820776C0FE9}" ; rdfs:comment "The decision state was recorded with substantially complete information."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . marvin:InfoCompletenessPartial a marvin:ClassOfDevelopmentDecisionStateByInfoCompleteness ; rdfs:label "Info Completeness: Partial"@en-gb ; dcterms:identifier "{A69AD5C7-A923-4AA3-82BC-81A8B6D63BAF}" ; rdfs:comment "The decision state was recorded with significant gaps in available information."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . marvin:InfoCompletenessPreliminary a marvin:ClassOfDevelopmentDecisionStateByInfoCompleteness ; rdfs:label "Info Completeness: Preliminary"@en-gb ; dcterms:identifier "{97193500-7522-4FA1-8020-2C25FBEAAD5A}" ; rdfs:comment "An early-stage decision state recorded with minimal information; expected to be revisited."@en-gb ; rdfs:subClassOf marvin:DevelopmentDecisionState . # -------------------------------------------------------------------------- # marvin:CorpusFileStatusAbsent ClassOfCorpusFileStateBySyncStatus (DD-010) # -------------------------------------------------------------------------- marvin:ClassOfCorpusFileStateBySyncStatus a rdfs:Class ; rdfs:label "Class of Corpus File State by Sync Status"@en-gb ; dcterms:identifier "{D5E4F3A2-B1C0-4D9E-8F76-5A4B3C2D1E0F}" ; rdfs:comment """Controlled vocabulary classifying indexer-layer marvin:CorpusFile nodes by their indexer-pipeline status. Each entry types a marvin:CorpusFileState individual linked to the corpus file via ies:isStateOf, enabling point-in-time status queries. Parallels marvin:ClassOfOntologyArtefactStateBySyncStatus (H.1) at the indexer layer. The same temporal-topology rule applies: the default \"currently present on disk\" condition is not a value in this taxonomy — it is represented by the absence of a closing ies:BoundingState on the latest CorpusFileState (per DD-005's Pattern B, applied to the indexer layer by DD-010). Asserting \"current\" as an rdf:type would be a 3D-ist leak. Membership is closed: adding a value requires a governance decision. """@en-gb ; rdfs:subClassOf marvin:ClassOfCorpusFileState . marvin:CorpusFileStatusAbsent a marvin:ClassOfCorpusFileStateBySyncStatus ; rdfs:label "Corpus File Status: Absent"@en-gb ; dcterms:identifier "{E6F5A4B3-C2D1-4E0F-9A87-6B5C4D3E2F1A}" ; rdfs:comment """The corpus file was indexed in a prior pass but is no longer present on disk. The whole-life marvin:CorpusFile is retained per the NoNodeDeletion principle; the latest CorpusFileState carries a closing ies:BoundingState and this typing assertion. No successor state opens. """@en-gb ; rdfs:subClassOf marvin:CorpusFileState . # -------------------------------------------------------------------------- # H.7 RejectedAlternativeStatus (DD-008) # -------------------------------------------------------------------------- marvin:RejectedAlternativeStatus a owl:Class ; rdfs:label "Rejected Alternative Status"@en-gb ; dcterms:identifier "{0E3F2A1B-4C5D-4E6F-8A7B-9C0D1E2F3A4B}" ; rdfs:comment """Controlled vocabulary classifying marvin:RejectedAlternative instances by the kind of grounding on which their rejection rests. Values are the two named individuals marvin:ArgumentRefuted and marvin:EmpiricallyRefuted, linked from each RejectedAlternative via marvin:rejectionEpistemicStatus (exactly one). The distinction is epistemic, not lifecycle. ArgumentRefuted and EmpiricallyRefuted describe what kind of evidence the rejection rests on; they do not describe the lifecycle of the RejectedAlternative itself (whether it has been withdrawn, superseded, or reclassified out of scope). Lifecycle-axis values would sit on a different property, not on marvin:rejectionEpistemicStatus. See DD-008 § Decision Q3 for the axis distinction and the rationale for holding the line at the two attested values. Closed range under DD-008 / [#116](https://github.com/aigora-de/marvin/issues/116): SHACL sh:in over the two named individuals; sh:minCount 1 sh:maxCount 1 on marvin:rejectionEpistemicStatus. New values require a schema PR with their own grounded rationale. Concept-scheme, not classification axis. Unlike the ClassOfX-By-Y vocabularies elsewhere in Section H, this taxonomy does not classify states — its values are individuals (concept-scheme members), not classes. The class is anchored to skos:Concept rather than to marvin:ClassOfX because marvin:RejectedAlternative is not state-typed at v0.2.10 (DD-008 § Decision Q2, conditional on [#94](https://github.com/aigora-de/marvin/issues/94) Question 3; see [#125](https://github.com/aigora-de/marvin/issues/125) for the named follow-up audit). The named individuals are typed both as marvin:RejectedAlternativeStatus (the vocabulary they belong to) and as skos:Concept (signalling the concept-scheme nature of their membership). This implements DD-008 Q1 Option A ("concept-scheme individuals + linking property") in the most literal sense available — the values are SKOS concepts. If [#94](https://github.com/aigora-de/marvin/issues/94) Question 3 lands state-typed and the [#125](https://github.com/aigora-de/marvin/issues/125) audit triggers a migration, marvin:rejectionEpistemicStatus would re-anchor from marvin:RejectedAlternative to a new marvin:RejectedAlternativeState. The value vocabulary (marvin:ArgumentRefuted, marvin:EmpiricallyRefuted) does NOT change shape — the named individuals remain skos:Concept-typed members of marvin:RejectedAlternativeStatus, and the property's range stays unchanged. This is what made Option A's concept-scheme framing migration-stable under either Q2 outcome (DD-008 § Q1 Decision and § Q2 conditional posture (c)). """@en-gb ; rdfs:subClassOf skos:Concept . marvin:ArgumentRefuted a marvin:RejectedAlternativeStatus, skos:Concept ; rdfs:label "Argument Refuted"@en-gb ; dcterms:identifier "{1F4A3B2C-5D6E-4F7A-9B8C-0D1E2F3A4B5C}" ; rdfs:comment """The rejection is grounded in panel-review reasoning. The rationale is argumentative; no executed pipeline output is cited as contradicting the alternative. Prose-prefix rendering on the rejected alternative's rdfs:comment: [Argument refuted]. The case-style mismatch between IRI form (ArgumentRefuted) and prose form (Argument refuted) is intentional; see DD-008 § Decision Q4. """@en-gb . marvin:EmpiricallyRefuted a marvin:RejectedAlternativeStatus, skos:Concept ; rdfs:label "Empirically Refuted"@en-gb ; dcterms:identifier "{2A5B4C3D-6E7F-4A8B-AC9D-1E2F3A4B5C6D}" ; rdfs:comment """The rejection is grounded in executed pipeline output that contradicts the alternative. The rationale cites the observed triples or behaviour, not panel-review reasoning alone. Prose-prefix rendering on the rejected alternative's rdfs:comment: [Empirically refuted]. The case-style mismatch between IRI form (EmpiricallyRefuted) and prose form (Empirically refuted) is intentional; see DD-008 § Decision Q4. """@en-gb . marvin:rejectionEpistemicStatus a owl:ObjectProperty ; rdfs:label "rejection epistemic status"@en-gb ; dcterms:identifier "{3B6C5D4E-7F8A-4B9C-BD0E-2F3A4B5C6D7E}" ; rdfs:comment """Links a marvin:RejectedAlternative to the kind of grounding on which its rejection rests. Value is one of the two named individuals declared in this section: marvin:ArgumentRefuted or marvin:EmpiricallyRefuted. Cardinality. SHACL shape filed as an obligation against [#116](https://github.com/aigora-de/marvin/issues/116) declares sh:minCount 1; sh:maxCount 1 on this property — exactly one status per RejectedAlternative. The schema does not encode the cardinality directly (OWL cardinality assertions are not used elsewhere in marvin-schema.ttl); enforcement lives in the SHACL shape and in CI. Domain anchor. The property hangs directly on marvin:RejectedAlternative (not on a marvin:RejectedAlternativeState — no such class exists at v0.2.10). See DD-008 § Decision Q2 for the conditional posture, and [#125](https://github.com/aigora-de/marvin/issues/125) for the named follow-up audit triggered when [#94](https://github.com/aigora-de/marvin/issues/94) Question 3 closes. See DD-008 for the full design rationale and the rejected alternatives (Q1 Options B and C). """@en-gb ; rdfs:domain marvin:RejectedAlternative ; rdfs:range marvin:RejectedAlternativeStatus ; rdfs:subPropertyOf ies:relationship . # -------------------------------------------------------------------------- # H.8 ClassOfValidationCriterionByKind (DD-015, Amendments 1 & 2) # -------------------------------------------------------------------------- marvin:ClassOfValidationCriterionByKind a rdfs:Class ; rdfs:label "Class of Validation Criterion by Kind"@en-gb ; dcterms:identifier "{F11287E7-3CE4-417C-847A-AA039F52D92A}" ; rdfs:comment """Controlled vocabulary classifying marvin:ValidationCriterion instances by execution-engine kind -- the dimension on which the validation runner dispatches. Each entry is simultaneously an instance of this taxonomy meta-class and a subclass of marvin:ValidationCriterion; a criterion is typed directly with the entry (e.g. a marvin:SparqlAskCriterion). Unlike the Section H taxonomies above it, this one classifies a whole-life Asset (marvin:ValidationCriterion), not a state: a criterion's kind is fixed for its lifetime. The whole-life classification is legitimate and already precedented (marvin:WorkOfDocumentationByCorpusDocumentType); the check-taxonomy-entry-subclassof-target CI check admits any ies:/marvin:-namespaced superclass, not only FooState classes. Four entries. The taxonomy is open: adding a kind requires a governance decision (a DD) and runner support -- DD-015 Amendment 2 added marvin:SparqlSelectCriterion as the precedent for that. See DD-015 (Amendments 1 & 2) and Issues #82, #59. """@en-gb ; rdfs:subClassOf marvin:ClassOfValidationCriterion . marvin:SparqlAskCriterion a marvin:ClassOfValidationCriterionByKind ; rdfs:label "SPARQL ASK Criterion"@en-gb ; dcterms:identifier "{A8763514-A1BA-4A13-B823-F6164A3A2BF8}" ; rdfs:comment """A ValidationCriterion whose check is a SPARQL ASK query, carried inline in marvin:criterionExpression. The runner executes the ASK against the backend; an ASK returning true is the FAIL condition. """@en-gb ; rdfs:subClassOf marvin:ValidationCriterion . marvin:SparqlSelectCriterion a marvin:ClassOfValidationCriterionByKind ; rdfs:label "SPARQL SELECT Criterion"@en-gb ; dcterms:identifier "{B2712B8F-075D-49BE-B82A-34C366838352}" ; rdfs:comment """A ValidationCriterion whose check is a SPARQL SELECT query, carried inline in marvin:criterionExpression. The runner executes the SELECT against the backend; a result set with at least one row is the FAIL condition (an empty result set is a PASS), and each row is one offending case. Unlike a marvin:SparqlAskCriterion, whose ASK yields a boolean and so cannot populate marvin:offendingSubject, a SELECT criterion is the SPARQL kind that reports per-subject detail: the first projected variable of each row binds an offending subject (written as a capped marvin:offendingSubject sample on the FailResult, with marvin:offendingSubjectCount carrying the true total), and the row contents are serialised into marvin:resultMessage. Use the ASK kind for a boolean gate, the SELECT kind for a diagnostic that hands the operator a list to act on. Authoring contract: a SELECT-criterion author MUST project the offending subject as the query's first variable -- the runner reads it by projection position, not by variable name. See DD-015 (Amendment 2); first consumer DD-016 / Issue #59. """@en-gb ; rdfs:subClassOf marvin:ValidationCriterion . marvin:ShaclCriterion a marvin:ClassOfValidationCriterionByKind ; rdfs:label "SHACL Criterion"@en-gb ; dcterms:identifier "{77B67B9F-340E-4D56-AC22-9EDE4BF0B7FA}" ; rdfs:comment """A ValidationCriterion whose check is a SHACL shape. marvin:criterionArtefact carries a repository-relative path to a validation/shacl/*.shapes.ttl file; the runner executes it via pyshacl and adapts the report into the marvin:CriterionResult. """@en-gb ; rdfs:subClassOf marvin:ValidationCriterion . marvin:PytestCriterion a marvin:ClassOfValidationCriterionByKind ; rdfs:label "pytest Criterion"@en-gb ; dcterms:identifier "{A2992418-1370-4B8D-BB50-8360256567D6}" ; rdfs:comment """A ValidationCriterion realised as a pytest test; marvin:criterionArtefact carries a pytest node id. The alpha validation runner records such a criterion but does not execute it -- it emits a marvin:CriterionResult typed marvin:SkippedResult (the test runs in the normal pytest suite). See DD-015 decision 3. """@en-gb ; rdfs:subClassOf marvin:ValidationCriterion . # -------------------------------------------------------------------------- # H.9 ClassOfCriterionResultByOutcome (DD-015, Amendment 1) # -------------------------------------------------------------------------- marvin:ClassOfCriterionResultByOutcome a rdfs:Class ; rdfs:label "Class of Criterion Result by Outcome"@en-gb ; dcterms:identifier "{6A887275-DF34-4AC7-8174-2A0EEDD5193E}" ; rdfs:comment """Controlled vocabulary classifying marvin:CriterionResult instances by outcome. Each entry is simultaneously an instance of this taxonomy meta-class and a subclass of marvin:CriterionResult; a result is typed directly with the entry (e.g. a marvin:FailResult). A CriterionResult is immutable -- its outcome is fixed at the moment of the run -- so classifying it by rdf:type rather than by a temporal state is correct: there is no later moment at which the outcome could change and leave the type stale. Membership is closed: three entries. See DD-015 (Amendment 1). """@en-gb ; rdfs:subClassOf marvin:ClassOfCriterionResult . marvin:PassResult a marvin:ClassOfCriterionResultByOutcome ; rdfs:label "Pass Result"@en-gb ; dcterms:identifier "{F2C0ABEB-8CC8-49A4-BE7C-869504A94364}" ; rdfs:comment "A CriterionResult recording that its criterion executed and its condition was satisfied."@en-gb ; rdfs:subClassOf marvin:CriterionResult . marvin:FailResult a marvin:ClassOfCriterionResultByOutcome ; rdfs:label "Fail Result"@en-gb ; dcterms:identifier "{75958D68-ECF9-4090-9674-20F28A2EFC9B}" ; rdfs:comment """A CriterionResult recording that its criterion executed and its condition was violated. Carries marvin:offendingSubject / marvin:offendingSubjectCount and marvin:resultMessage. """@en-gb ; rdfs:subClassOf marvin:CriterionResult . marvin:SkippedResult a marvin:ClassOfCriterionResultByOutcome ; rdfs:label "Skipped Result"@en-gb ; dcterms:identifier "{D0BAD5D6-2822-4FCF-9355-71E319E81458}" ; rdfs:comment """A CriterionResult recording that its criterion was not executed by the runner. At alpha this is the outcome for pytest-kind criteria (marvin:PytestCriterion). See DD-015 decision 3. """@en-gb ; rdfs:subClassOf marvin:CriterionResult . # -------------------------------------------------------------------------- # H.10 FindingKind (DD-018) # -------------------------------------------------------------------------- marvin:FindingKind a owl:Class ; rdfs:label "Finding Kind"@en-gb ; dcterms:identifier "{A68B2DFA-937C-4ABC-B7BF-8F9AD309ADDB}" ; rdfs:comment """Controlled vocabulary classifying marvin:Finding instances by the kind of observation a finding records. Values are the three named individuals marvin:SubstantiveFinding, marvin:HousekeepingFinding, and marvin:ScopeGapFinding, linked from each Finding via marvin:findingKind. Concept-scheme, not classification axis. Like marvin:RejectedAlternativeStatus (H.7), and unlike the ClassOfX-By-Y powertype vocabularies elsewhere in Section H, this taxonomy does not classify states or whole-life entities by rdf:type -- its values are individuals (concept-scheme members) reached through a discriminator property (marvin:findingKind), not classes a Finding is typed with. The class is anchored to skos:Concept; each named individual is typed both marvin:FindingKind (the vocabulary it belongs to) and skos:Concept. This is the structural twin of marvin:rejectionEpistemicStatus over marvin:RejectedAlternativeStatus. Naming. A concept-scheme vocabulary takes a non-"ClassOf" name -- as marvin:RejectedAlternativeStatus does -- because check-taxonomy-entry-subclassof-target.rq requires every marvin:ClassOf... taxonomy entry to carry rdfs:subClassOf, which concept-scheme members deliberately lack. DD-018's illustrated name marvin:ClassOfFindingByKind predates the Phase-2 concept-scheme decision and is superseded by this name; see DD-018 Amendment 2. Membership is closed: three entries. Adding a value requires a schema PR with its own grounded rationale. See DD-018. """@en-gb ; rdfs:subClassOf skos:Concept . marvin:SubstantiveFinding a marvin:FindingKind, skos:Concept ; rdfs:label "Substantive Finding"@en-gb ; dcterms:identifier "{747CF847-BDCD-4F1E-917B-05563B271145}" ; rdfs:comment "A finding that records a substantive observation -- a modelling, design, or correctness concern bearing on the artefact under review."@en-gb . marvin:HousekeepingFinding a marvin:FindingKind, skos:Concept ; rdfs:label "Housekeeping Finding"@en-gb ; dcterms:identifier "{A78B653D-CD81-40B9-BA78-AD48EF82C677}" ; rdfs:comment "A finding that records a housekeeping observation -- a label, comment, formatting, or hygiene point that does not bear on substantive correctness."@en-gb . marvin:ScopeGapFinding a marvin:FindingKind, skos:Concept ; rdfs:label "Scope-Gap Finding"@en-gb ; dcterms:identifier "{B1A2E53D-101B-4FDA-846D-9F2AC81D4BB4}" ; rdfs:comment "A finding that records a gap in scope -- something the artefact does not cover that arguably should. A scope-gap finding typically spawns a marvin:OpenTension; the finding-kind classifies the observation, not the follow-up artefact."@en-gb . marvin:findingKind a owl:ObjectProperty ; rdfs:label "finding kind"@en-gb ; dcterms:identifier "{D34EB61D-6195-4815-A618-D9F51CB626AC}" ; rdfs:comment """Discriminator: the kind of observation a marvin:Finding records, over the closed set of named individuals in marvin:FindingKind. A property-based discriminator over a concept-scheme vocabulary, mirroring marvin:rejectionEpistemicStatus (H.7). Cardinality (one per Finding) is a SHACL obligation, not encoded here. See DD-018. """@en-gb ; rdfs:domain marvin:Finding ; rdfs:range marvin:FindingKind ; rdfs:subPropertyOf ies:relationship . # -------------------------------------------------------------------------- # H.11 FindingOutcome (DD-018) # -------------------------------------------------------------------------- marvin:FindingOutcome a owl:Class ; rdfs:label "Finding Outcome"@en-gb ; dcterms:identifier "{50869832-6941-4A14-9DCC-7F5F76C585FA}" ; rdfs:comment """Controlled vocabulary classifying marvin:Finding instances by what the review decided to do with the finding. Values are the five named individuals marvin:Adopted, marvin:Deferred, marvin:Forwarded, marvin:RecordedAsOpenTension, and marvin:Dissenting, linked from each Finding via marvin:findingOutcome. Concept-scheme, not classification axis -- the same structural treatment as marvin:FindingKind (H.10) and marvin:RejectedAlternativeStatus (H.7): anchored to skos:Concept, each named individual dual-typed marvin:FindingOutcome and skos:Concept, reached through a discriminator property rather than asserted as an rdf:type of the Finding. The outcome classifies the finding and must not be conflated with the identity of any follow-up artefact: a marvin:RecordedAsOpenTension finding spawns a marvin:OpenTension and a marvin:Forwarded finding a GitHub issue, but the outcome names what the review did with the finding, not those artefacts. Naming. (1) Non-"ClassOf", for the same reason as marvin:FindingKind (H.10): a concept-scheme vocabulary's entries carry no rdfs:subClassOf. (2) "Outcome", not "Disposition": IES Common defines ies:DispositionalClass (with ies:Capability / ies:Tendency) for real-world dispositions -- capabilities and tendencies. The resolution sense of "disposition" used in DD-018's prose is a distinct word-sense; to avoid a homonym with a core IES class in the same imported graph, the schema uses "outcome". DD-018's illustrated name marvin:ClassOfFindingByDisposition is superseded by this name; see DD-018 Amendment 2. Membership is closed: five entries. See DD-018. """@en-gb ; rdfs:subClassOf skos:Concept . marvin:Adopted a marvin:FindingOutcome, skos:Concept ; rdfs:label "Adopted"@en-gb ; dcterms:identifier "{00790A46-8FD7-4F82-BE0C-4F458842DB9E}" ; rdfs:comment "Finding outcome: the review accepted the finding and acted on it."@en-gb . marvin:Deferred a marvin:FindingOutcome, skos:Concept ; rdfs:label "Deferred"@en-gb ; dcterms:identifier "{58C3AEE4-52C0-48EE-BAAE-83321FFE7EA5}" ; rdfs:comment "Finding outcome: the review acknowledged the finding but deferred action to later work."@en-gb . marvin:Forwarded a marvin:FindingOutcome, skos:Concept ; rdfs:label "Forwarded"@en-gb ; dcterms:identifier "{04DA4B9C-9DA8-42A7-B6F0-608D69501E5B}" ; rdfs:comment "Finding outcome: the review forwarded the finding to another venue -- typically a GitHub issue -- for action outside the current review."@en-gb . marvin:RecordedAsOpenTension a marvin:FindingOutcome, skos:Concept ; rdfs:label "Recorded as Open Tension"@en-gb ; dcterms:identifier "{0EB1ABFA-35F0-4010-AD44-5953C3B8A1D7}" ; rdfs:comment "Finding outcome: the review consciously parked the finding, recording it as a marvin:OpenTension."@en-gb . marvin:Dissenting a marvin:FindingOutcome, skos:Concept ; rdfs:label "Dissenting"@en-gb ; dcterms:identifier "{E54F1AFD-078D-47FB-AFA1-DFBF45BF8155}" ; rdfs:comment "Finding outcome: a solo dissent -- one reviewer registering that they would have decided otherwise against a settled panel outcome. Asymmetric, one party against an outcome; not an ies:Disagreement, which is between parties. See DD-018 OQ1."@en-gb . marvin:findingOutcome a owl:ObjectProperty ; rdfs:label "finding outcome"@en-gb ; dcterms:identifier "{4E2D267A-119B-4F19-AEE3-5AB749919389}" ; rdfs:comment """Discriminator: what the review decided to do with a marvin:Finding, over the closed set of named individuals in marvin:FindingOutcome. A property-based discriminator over a concept-scheme vocabulary, mirroring marvin:rejectionEpistemicStatus (H.7). The marvin:Dissenting value carries a solo dissent (DD-018 OQ1). Cardinality is a SHACL obligation, not encoded here. See DD-018. """@en-gb ; rdfs:domain marvin:Finding ; rdfs:range marvin:FindingOutcome ; rdfs:subPropertyOf ies:relationship . # -------------------------------------------------------------------------- # H.12 ClassOfDevelopmentSessionStateByMode (DD-021) # -------------------------------------------------------------------------- marvin:ClassOfDevelopmentSessionStateByMode a rdfs:Class ; rdfs:label "Class of Development Session State by Mode"@en-gb ; dcterms:identifier "{F5AFC8A2-9373-4933-A55C-C5894230B2B2}" ; rdfs:comment """Controlled vocabulary of workflow modes, classifying marvin:DevelopmentSessionState instances. Each entry is simultaneously an instance of this taxonomy meta-class and a subclass of marvin:DevelopmentSessionState; a mode-stretch of a session is a DevelopmentSessionState typed directly with the entry (e.g. a marvin:DiscoveryMode), following the H.3 / H.4 dual-typing idiom for state classification. Closed membership: three modes -- discovery, development, closure. Closure is a distinct mode, not a sub-flavour of development: a closure-mode stretch surfaces gaps the working modes did not. A fourth mode would be a deliberate, panel-reviewed addition. See DD-021. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:DiscoveryMode a marvin:ClassOfDevelopmentSessionStateByMode ; rdfs:label "Discovery Mode"@en-gb ; dcterms:identifier "{34CCC477-86BF-4095-8F4C-41E9563ADD91}" ; rdfs:comment "Mode for novel requirements, high uncertainty, or concepts high in the conceptual hierarchy: exploration, alternatives, philosophical grounding."@en-gb ; rdfs:subClassOf marvin:DevelopmentSessionState . marvin:DevelopmentMode a marvin:ClassOfDevelopmentSessionStateByMode ; rdfs:label "Development Mode"@en-gb ; dcterms:identifier "{90179C4F-67EC-4B34-8517-7FC816A74C18}" ; rdfs:comment "Mode for routine extension work: consistency, pattern-matching, validation."@en-gb ; rdfs:subClassOf marvin:DevelopmentSessionState . marvin:ClosureMode a marvin:ClassOfDevelopmentSessionStateByMode ; rdfs:label "Closure Mode"@en-gb ; dcterms:identifier "{74708CB7-174C-4F0E-A5F2-DB0B425BD90E}" ; rdfs:comment "Mode for projecting and consolidating a completed workflow: closure-mode discovery surfaces gaps the working modes did not."@en-gb ; rdfs:subClassOf marvin:DevelopmentSessionState . # ========================================================================== # SECTION I -- Well-known instances: Principles # ========================================================================== a marvin:Principle ; rdfs:label "A/B Party Principle"@en-gb ; dcterms:identifier "{378B759A-B4A0-476C-9B14-275C80A63A29}" ; rdfs:comment """Before commencing development, there should ideally be a party A with information to share and a party B wanting to receive it. This grounds modelling concretely. Speculative development without A/B grounding should be flagged. """@en-gb . a marvin:Principle ; rdfs:label "Keep It Simple"@en-gb ; dcterms:identifier "{40A38F80-04B5-4C36-9D5C-47F65DA85980}" ; rdfs:comment "The goal is complex; the process should be as simple as possible while remaining expressive."@en-gb . a marvin:Principle ; rdfs:label "Leverage Open Source"@en-gb ; dcterms:identifier "{77985447-7F5F-487E-8F6C-B3B788098714}" ; rdfs:comment "Use open source works where they help; do not reinvent the wheel."@en-gb . a marvin:Principle ; rdfs:label "Rigour"@en-gb ; dcterms:identifier "{AD93E404-58CD-4525-8560-9A7BD23E3EC0}" ; rdfs:comment "Apply the same conceptual discipline to meta-level design as to any ontology extension."@en-gb . a marvin:Principle ; rdfs:label "Consistency"@en-gb ; dcterms:identifier "{BADDBC14-9340-4C78-8D21-A2966E63A52E}" ; rdfs:comment "Coherence with IES foundational commitments. Extensions must not contradict the base ontology."@en-gb . a marvin:Principle ; rdfs:label "Triple Store Abstraction"@en-gb ; dcterms:identifier "{317034BA-1E42-4B92-81CF-464ECC91E35A}" ; rdfs:comment """All code accesses the triple store exclusively through the TripleStoreBackend abstract interface. No store-specific types leak across the layer boundary. Exchange format is rdflib.Graph or SPARQL strings. CRITICAL architectural requirement from day one. """@en-gb . a marvin:Principle ; rdfs:label "No Node Deletion"@en-gb ; dcterms:identifier "{B30F55A3-C242-4E73-9115-D47F383CE1B4}" ; rdfs:comment """Nodes in the memory graph are never deleted. Superseded decisions receive ies:successorTo links. Absent artefacts are typed as marvin:SyncStatusAbsent. The graph only grows. """@en-gb . a marvin:Principle ; rdfs:label "Deterministic Pipeline IRIs"@en-gb ; dcterms:identifier "{A9B0C1D2-E3F4-4A5B-C6D7-E8F9A0B1C2D5}" ; rdfs:comment """Every IRI minted by a Marvin pipeline is a deterministic function of the node's logical-identity tuple. Re-invocation with the same logical inputs produces the same IRIs (under the pipeline short-circuit mechanism) or no writes at all. Templates are declared in this schema via marvin:iriTemplate and are transparent composites of logical inputs, not content hashes. See DD-007. """@en-gb . # ========================================================================== # SECTION J -- Corpus classes and taxonomies # ========================================================================== marvin:CorpusFile a rdfs:Class ; rdfs:label "Corpus File"@en-gb ; dcterms:identifier "{C9A3E21F-4B78-4D56-A3F2-1E8D7C9B0A5F}" ; rdfs:comment """An IndividualDocument representing a specific file in Marvin's document corpus. Indexer-layer; created and maintained exclusively by the Marvin corpus indexer pipeline. Whole-life entity. Under DD-010 (v0.2.9), marvin:CorpusFile is the whole-life individual representing the file as a copy of its ies:WorkOfDocumentation across all ingest events. Each ingest produces a new marvin:CorpusFileState (linked via ies:isStateOf), carrying the per-ingest checksum, ingest timestamp, and revision number; state-level details are bounded by ies:BoundingState instances per Pattern B (DD-005). The whole-life CorpusFile IRI is stable across re-ingests. Every CorpusFile must carry: - marvin:filePath (xsd:string, relative to corpus root) - ies:aCopyOf (artefact-layer ies:WorkOfDocumentation instance) - ies:formatOfIndividualDocument (DocumentFormatValue instance) Optionally carries (legacy / convenience): - marvin:fileChecksum (the latest CorpusFileState carries the authoritative per-ingest value; a literal on the whole-life CorpusFile is retained under DD-010's dual-declaration default for legacy ABox query compatibility) - marvin:ingestTimestamp (same disposition as fileChecksum) Replication-edge. CorpusFiles that are verbatim copies of upstream IndividualDocuments link to those upstream copies via marvin:replicatedFrom. The upstream-anchor is non-tracked (no fileChecksum, no ingestTimestamp, no state chain, not a marvin:CorpusFile). See DD-011 and Section L for the upstream- anchor IRI template. The ies:aCopyOf property is rdfs:subPropertyOf rdf:type; asserting it simultaneously asserts that this CorpusFile is a member of the referenced WorkOfDocumentation. """@en-gb ; rdfs:subClassOf ies:IndividualDocument . marvin:CorpusFileState a rdfs:Class ; rdfs:label "Corpus File State"@en-gb ; dcterms:identifier "{F4A3B2C1-D0E9-4F8A-7B6C-5D4E3F2A1B0C}" ; rdfs:comment """A temporal state of a marvin:CorpusFile representing a single indexer ingest event. Carries per-ingest checksum, ingest timestamp, and revision number. Successive states are linked via prov:wasRevisionOf (new state -> old state), with Pattern B bounding via ies:BoundingState (closing on the predecessor, opening on the successor, sharing the same ies:ParticularPeriod at the boundary). Parallels marvin:CompiledDocumentState at the indexer layer. The whole-life thing is \"the file as a copy of the work\" (one marvin:CorpusFile per ies:WorkOfDocumentation per corpus); the temporal parts are \"the bytes-on-disk states across re-ingests\". Compile-pipeline integration. The compile pipeline's SummariseStage targets the latest marvin:CorpusFileState (not the whole-life CorpusFile) on prov:hadPrimarySource writes; the compile-pipeline SC dispatcher reads the latest CorpusFileState's marvin:fileChecksum (topologically current per the absence of a closing ies:BoundingState) for staleness detection. IRI template (Section L): https://w3id.org/marvin/corpus-file-state/{work-slug}/rev-{n} Logical-composite over (work-slug, n) per DD-007's default rule. One stream of states per CorpusFile. See DD-010 for the full design rationale, DD-005 for the Pattern B precedent, and DD-006 for the commit_atomic boundary discipline that bounding writes rely on. """@en-gb ; ies:powertype marvin:ClassOfCorpusFileState ; rdfs:subClassOf ies:AssetState . marvin:ClassOfCorpusFileState a rdfs:Class ; rdfs:label "Class Of Corpus File State"@en-gb ; dcterms:identifier "{05B4A3C2-D1E0-4F9A-8B7C-6D5E4F3A2B1C}" ; rdfs:comment """The powertype of marvin:CorpusFileState. Taxonomy classes that classify indexer-layer states subclass this — see marvin:ClassOfCorpusFileStateBySyncStatus (Section H.6). Note: ies:ClassOfAssetState is not defined in IES Common v5; ies:ClassOfState is used as the parent. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:filePath a owl:DatatypeProperty ; rdfs:label "file path"@en-gb ; dcterms:identifier "{3F7A1B2C-8D9E-4F5A-B6C7-2E1D0A3F4B5C}" ; rdfs:comment """Path to the file relative to the corpus root directory. Must be stable across indexer runs; changes indicate a moved file (create new CorpusFile, mark old as SyncStatusAbsent). """@en-gb ; rdfs:domain marvin:CorpusFile ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:fileChecksum a owl:DatatypeProperty ; rdfs:label "file checksum"@en-gb ; dcterms:identifier "{4A8B2C3D-9E0F-4A6B-C7D8-3F2E1A4B5C6D}" ; rdfs:comment """SHA-256 checksum of the file content at the time of an indexer ingest. Used by the compile pipeline for staleness detection: a compiled document is stale when the current marvin:fileChecksum on the latest marvin:CorpusFileState differs from marvin:sourceChecksumAtCompile on the marvin:CompiledDocumentState. Indexer-layer SC compares the on-disk content's SHA-256 against the latest CorpusFileState's marvin:fileChecksum. Domain scope. v0.2.9 extends the property's domain from marvin:CorpusFile alone to a union of marvin:CorpusFile and marvin:CorpusFileState, paired with DD-010's introduction of the indexer-layer state-chain. The authoritative per-ingest value lives on the CorpusFileState; the literal on the whole-life CorpusFile is retained under DD-010's dual-declaration default for legacy ABox query compatibility (Phase 2 panel-decided default; whether to ultimately remove the property from CorpusFile post-migration is deferred to a separate DD). """@en-gb ; rdfs:domain [ a owl:Class ; owl:unionOf ( marvin:CorpusFile marvin:CorpusFileState ) ] ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:ingestTimestamp a owl:DatatypeProperty ; rdfs:label "ingest timestamp"@en-gb ; dcterms:identifier "{5B9C3D4E-0F1A-4B7C-D8E9-4A3F2B5C6D7E}" ; rdfs:comment """UTC datetime of a pipeline operation that wrote or updated a node. Used on: - marvin:CorpusFile (whole-life, last ingest event; retained for legacy ABox compatibility under DD-010's dual-declaration default) - marvin:CorpusFileState (per-ingest, authoritative under DD-010) - marvin:CompiledDocumentState (per-compile) Typed xsd:dateTimeStamp to allow direct SPARQL temporal comparison. Domain scope. v0.2.9 extends the existing owl:unionOf(marvin:CorpusFile, marvin:CompiledDocumentState) to include marvin:CorpusFileState, paired with DD-010's state-chain introduction. """@en-gb ; rdfs:domain [ a owl:Class ; owl:unionOf ( marvin:CorpusFile marvin:CorpusFileState marvin:CompiledDocumentState ) ] ; rdfs:range xsd:dateTimeStamp ; rdfs:subPropertyOf ies:attribute . marvin:workSlug a owl:DatatypeProperty ; rdfs:label "work slug"@en-gb ; dcterms:identifier "{F8B9C0D1-E2F3-4A5B-C6D7-E8F9A0B1C2D4}" ; rdfs:comment """A maintained, stable, human-chosen identifier for an artefact-layer ies:WorkOfDocumentation. Format: ^[a-z][a-z0-9-]{2,63}$ — kebab-case ASCII, starting with a letter, length 3–64 characters. The slug is the work-identity anchor used by Marvin pipelines when minting IRIs: see DD-007. In compile-pipeline IRI templates it populates the {work-slug} variable. The slug is stable across file renames and byte-level source changes. CI enforcement (Issue #55, narrowed; see DD-007 Consequences "CI enforcement" table): * Format — CI-enforced against any marvin:workSlug literal under ontology/*.ttl (validation/sparql/check-work-slug-format.rq). * Uniqueness within the repository — CI-enforced against the combined ontology/*.ttl graph (validation/sparql/check-work-slug-uniqueness.rq). * Presence on project-owned ies:WorkOfDocumentation instances — CI-enforced against ontology/*.ttl (validation/sparql/check-work-slug-presence.rq). Scoped to the project's own instances, not arbitrary WorkOfDocumentation instances in a populated Memory Graph; ABox-graph verification is Issue #60's validation-pipeline responsibility. * Stability across commits — not CI-enforced. The guidance below that slugs are not changed is an unenforced contract; a CI tripwire remains open DD-007 future work. If a slug must change (exceptional cases), the procedure is governed by a future DD; slug reassignment is not an ordinary edit and produces an orphaned CompiledDocument IRI under NoNodeDeletion. Declared on ies:WorkOfDocumentation rather than on marvin:CorpusFile because the slug identifies the work, not any particular file serving as a copy of it. The link between corpus file and work is ies:aCopyOf. Naming rationale. The property is named marvin:workSlug (not marvin:sourceSlug) per panel review on PR #36. The slug names what it identifies (a WorkOfDocumentation) rather than what it is used for in any specific pipeline (where it may be a 'source' in the compile pipeline, an input to the sync pipeline, etc.). See DD-007 for the panel's reasoning. Compare marvin:artefactSlug (this section), which applies the same DD-007 "anchor identity to something stable and maintained" rule to a class whose stable identifier is owned upstream: workSlug is human-maintained because a Marvin WorkOfDocumentation has no upstream identifier to defer to; artefactSlug is machine-derived from the source IES IRI because that IRI is itself the upstream-maintained identifier. One rule, two cases. """@en-gb ; rdfs:domain ies:WorkOfDocumentation ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:artefactSlug a owl:DatatypeProperty ; rdfs:label "artefact slug"@en-gb ; dcterms:identifier "{4B7C9D5E-3F2A-4D8E-A1B6-9F0C8D7E6A5B}" ; rdfs:comment """A stable, machine-derived identifier for a marvin:OntologyArtefact. Format: ^[a-z][a-z0-9-]{2,127}$ — kebab-case ASCII, starting with a letter, length 3–128 characters. The 128-character upper bound (raised from marvin:workSlug's 64) accommodates IES's longer camelCase local names without truncation risk. The slug is the artefact-identity anchor used by the sync pipeline when minting IRIs for marvin:OntologyArtefactState and for existence-layer artefact IRIs themselves: see DD-007 and Issue #53. It populates the {artefact-slug} variable in the IRI templates of Section L for marvin:ClassNode, marvin:PropertyNode, marvin:NamespaceNode, marvin:OntologyModule, marvin:OntologyLayer, and marvin:OntologyArtefactState; it also populates the {subject-slug} and {object-slug} variables of the marvin:AxiomNode template. AxiomNode itself does NOT carry an artefactSlug — its identity is its (subject, predicate, object) triple, expressed directly in its IRI. Derivation rule: artefactSlug = "{module-slug}--{kebab-cased-local-name}" where {module-slug} is the marvin:artefactSlug of the marvin:OntologyModule the artefact is declared in (or the OntologyLayer's slug for layer-level artefacts), and {kebab-cased-local-name} is the local-name portion of the artefact's source IRI (post-'#' if a fragment, post-last-'/' otherwise) converted from camelCase to kebab-case and lower-cased. Example: ies:CommunicationsAccount in ies-common.ttl yields ies-common--communications-account. Slug semantics — same principle as marvin:workSlug, applied to a class whose identity is owned by someone else. DD-007 requires that a slug be anchored to something stable and maintained; workSlug satisfies that by being human-maintained because a marvin:WorkOfDocumentation in the Marvin corpus has no upstream identifier to defer to, so someone inside the project must commit to a handle. artefactSlug satisfies the same requirement by deferring to the upstream IES IRI, which is itself the stable maintained identifier — owned and maintained by the IES authors, not by Marvin. The slug is a deterministic projection of that upstream identifier onto the Marvin namespace. DD-007's warning against path-derived or file-hash-derived slugs was about anchoring identity to churnable local state. Anchoring artefact-identity to an IRI owned by a different project is not a deviation from that rule; it is the rule, applied to a case where the 'stable maintained thing' happens to live upstream. If the IES authors rename a concept, the slug changes because the upstream identity changed — which is the correct behaviour. See Issue #53 for the full design rationale and panel discussion. """@en-gb ; rdfs:domain marvin:OntologyArtefact ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:WorkOfDocumentationByCorpusDocumentType a rdfs:Class ; rdfs:label "Work of Documentation by Corpus Document Type"@en-gb ; dcterms:identifier "{6C0D4E5F-1A2B-4C8D-E9F0-5B4A3C6D7E8F}" ; rdfs:comment """Controlled vocabulary classifying ies:WorkOfDocumentation nodes by their primary purpose in the Marvin corpus. Entries are NOT mutually exclusive. A document may carry both DevelopmentRecord and UserFacing type assertions simultaneously. On transition, the new type is ADDED rather than substituted. Uses whole-life classification (not state-based) because IES v5 does not define a WorkOfDocumentationState class. Membership is closed. """@en-gb ; rdfs:subClassOf ies:ClassOfIndividualDocument . marvin:CorpusDocumentTypeDevelopmentRecord a marvin:WorkOfDocumentationByCorpusDocumentType ; rdfs:label "Corpus Document Type: Development Record"@en-gb ; dcterms:identifier "{7D1E5F6A-2B3C-4D9E-F0A1-6C5B4D7E8F9A}" ; rdfs:comment """Records development context, decisions, rationale, rejected alternatives, tensions, or session history. Append-only lifecycle. Not mutually exclusive with UserFacing. """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:CorpusDocumentTypeUserFacing a marvin:WorkOfDocumentationByCorpusDocumentType ; rdfs:label "Corpus Document Type: User Facing"@en-gb ; dcterms:identifier "{8E2F6A7B-3C4D-4EAF-A1B2-7D6C5E8F9A0B}" ; rdfs:comment """Intended for data modellers, domain users, or newcomers: definitions, patterns, worked examples, narrative accompanying an ontology module. Versioned lifecycle (ies:successorTo). Not mutually exclusive with DevelopmentRecord. """@en-gb ; rdfs:subClassOf ies:WorkOfDocumentation . marvin:ClassOfAssetStateByCorpusRole a rdfs:Class ; rdfs:label "Class of Asset State by Corpus Role"@en-gb ; dcterms:identifier "{9F3A7B8C-4D5E-4FAF-B2C3-8E7D6F9A0B1C}" ; rdfs:comment """Controlled vocabulary classifying the pipeline role of a CorpusFile at a point in time. Each entry types an ies:AssetState individual linked to the CorpusFile via ies:isStateOf. Membership is closed. """@en-gb ; rdfs:subClassOf ies:ClassOfState . marvin:CorpusRoleSource a marvin:ClassOfAssetStateByCorpusRole ; rdfs:label "Corpus Role: Source"@en-gb ; dcterms:identifier "{A04B8C9D-5E6F-4A0B-C3D4-9F8E7A0B1C2D}" ; rdfs:comment "Ingested from outside the Marvin project as raw input."@en-gb ; rdfs:subClassOf ies:AssetState . marvin:CorpusRoleWorking a marvin:ClassOfAssetStateByCorpusRole ; rdfs:label "Corpus Role: Working"@en-gb ; dcterms:identifier "{B15C9D0E-6F7A-4B1C-D4E5-0A9F8B1C2D3E}" ; rdfs:comment "Created or edited within the Marvin workflow."@en-gb ; rdfs:subClassOf ies:AssetState . marvin:CorpusRoleCompiled a marvin:ClassOfAssetStateByCorpusRole ; rdfs:label "Corpus Role: Compiled"@en-gb ; dcterms:identifier "{C26D0E1F-7A8B-4C2D-E5F6-1B0A9C2D3E4F}" ; rdfs:comment """Produced by the compile pipeline. A CompiledDocument node exists in the artefact layer linked via ies:aCopyOf. """@en-gb ; rdfs:subClassOf ies:AssetState . marvin:CorpusRoleOntologyArtefact a marvin:ClassOfAssetStateByCorpusRole ; rdfs:label "Corpus Role: Ontology Artefact"@en-gb ; dcterms:identifier "{D37E1F2A-8B9C-4D3E-F6A7-2C1B0D3E4F5A}" ; rdfs:comment """A .ttl or other ontology file managed as a primary artefact. The authoritative node is the existence-layer OntologyModule. This CorpusFile links via ies:aCopyOf to an ies:WorkOfDocumentation instance, which links to the OntologyModule via ies:documentedBy (Option D, issue #10: direct ies:WorkOfDocumentation, no marvin:CorpusWork subclass). """@en-gb ; rdfs:subClassOf ies:AssetState . marvin:ClassOfIndividualDocumentByDocumentFormat a rdfs:Class ; rdfs:label "Class of Individual Document by Document Format"@en-gb ; dcterms:identifier "{E48F2A3B-9C0D-4E4F-A7B8-3D2C1E4F5A6B}" ; rdfs:comment """Controlled vocabulary of document formats used in the Marvin corpus. Entries are ies:DocumentFormat instances, usable with ies:format (on WorkOfDocumentation) and ies:formatOfIndividualDocument (on IndividualDocument). Membership is closed. """@en-gb ; rdfs:subClassOf ies:ClassOfIndividualDocument . marvin:DocumentFormatMarkdown a marvin:ClassOfIndividualDocumentByDocumentFormat, ies:DocumentFormat ; rdfs:label "Document Format: Markdown"@en-gb ; dcterms:identifier "{F59A3B4C-0D1E-4F5A-B8C9-4E3D2F5A6B7C}" ; rdfs:comment ".md files. Markdown prose documents."@en-gb ; rdfs:subClassOf ies:IndividualDocument . marvin:DocumentFormatTurtle a marvin:ClassOfIndividualDocumentByDocumentFormat, ies:DocumentFormat ; rdfs:label "Document Format: Turtle"@en-gb ; dcterms:identifier "{A6B4C5D6-1E2F-4A6B-C9D0-5F4E3A6B7C8D}" ; rdfs:comment ".ttl files. RDF Turtle serialisation."@en-gb ; rdfs:subClassOf ies:IndividualDocument . marvin:DocumentFormatPDF a marvin:ClassOfIndividualDocumentByDocumentFormat, ies:DocumentFormat ; rdfs:label "Document Format: PDF"@en-gb ; dcterms:identifier "{B7C5D6E7-2F3A-4B7C-D0E1-6A5F4B7C8D9E}" ; rdfs:comment ".pdf files. Portable Document Format."@en-gb ; rdfs:subClassOf ies:IndividualDocument . marvin:DocumentFormatPlainText a marvin:ClassOfIndividualDocumentByDocumentFormat, ies:DocumentFormat ; rdfs:label "Document Format: Plain Text"@en-gb ; dcterms:identifier "{C8D6E7F8-3A4B-4C8D-E1F2-7B6A5C8D9E0F}" ; rdfs:comment ".txt files. Unformatted plain text."@en-gb ; rdfs:subClassOf ies:IndividualDocument . marvin:DocumentFormatSVG a marvin:ClassOfIndividualDocumentByDocumentFormat, ies:DocumentFormat ; rdfs:label "Document Format: SVG"@en-gb ; dcterms:identifier "{D9E7F8A9-4B5C-4D9E-F2A3-8C7B6D9E0F1A}" ; rdfs:comment ".svg files. Scalable Vector Graphics."@en-gb ; rdfs:subClassOf ies:IndividualDocument . # -------------------------------------------------------------------------- # J.x marvin:IndexerShortCircuitDecision (DD-014, v0.2.12) # # Data-level pattern (indexer SC found the on-disk bytes unchanged, # pipeline emitted zero writes to the CorpusFileState chain): # # <:indexerShortCircuit_2026-05-13> # a marvin:IndexerShortCircuitDecision ; # marvin:shortCircuitedAgainstFile <:corpusFileState> ; # ies:inPeriod <:pp_2026-05-13T10:00:00Z> . # # The checksum value driving the short-circuit is recoverable as # ?sc marvin:shortCircuitedAgainstFile/marvin:fileChecksum # without duplicating the literal on the event node. The logical # indexing instant is carried by the ies:ParticularPeriod. # # Sibling-not-parent. marvin:IndexerShortCircuitDecision is a subclass # of marvin:ShortCircuitDecision (Section K.4) but lives in Section J # because the surface it operates on -- the marvin:CorpusFileState # chain -- is indexer-layer. The parent class's compile-pipeline # shape (predicate marvin:shortCircuitedAgainstState ranging over # marvin:CompiledDocumentState) does not apply to indexer-SC events: # the indexer has no compiled-output analogue, so the predicate is # simply not used on instances of this subclass. See DD-014 for the # B Q1 resolution and the rejected reuse-the-parent alternative. # -------------------------------------------------------------------------- marvin:IndexerShortCircuitDecision a rdfs:Class ; rdfs:label "Indexer Short-Circuit Decision"@en-gb ; dcterms:identifier "{B8C9D0E1-F2A3-4B8C-D9E0-F1A2B3C4D5E6}" ; rdfs:comment """An Event recording that the Marvin indexer's source-content- hash short-circuit check determined no new marvin:CorpusFileState was required for a given marvin:CorpusFile on a given indexer invocation. Emitted in place of a Pattern B closing/opening cluster on the CorpusFileState chain when the on-disk bytes' SHA-256 equals the marvin:fileChecksum on the latest marvin:CorpusFileState (topologically current per the absence of a closing ies:BoundingState). Queryable provenance of non-writes at the indexer layer, paralleling marvin:ShortCircuitDecision's role at the compile layer. An operator asking 'when did the indexer last short-circuit this CorpusFile?' deserves a SPARQL answer. Sibling to compile-SC. Subclass of marvin:ShortCircuitDecision (Section K.4). The two SC classes share the abstract notion of 'a decision recorded in place of a write' but differ in their target surface: compile-SC's marvin:shortCircuitedAgainstState ranges over marvin:CompiledDocumentState; indexer-SC has no equivalent target (the indexer produces no analogue to a compiled output -- the 'state we would otherwise re-derive' IS the marvin:CorpusFileState already pointed at by marvin:shortCircuitedAgainstFile). Indexer-SC instances therefore use marvin:shortCircuitedAgainstFile only. Links: - marvin:shortCircuitedAgainstFile -> marvin:CorpusFileState (the temporal part of the source whose checksum was evaluated; the whole-life CorpusFile is reachable via ies:isStateOf. Same predicate semantics as compile-SC -- no range widening, no heterogeneous-target overload.) - ies:inPeriod -> ies:ParticularPeriod (the logical instant at which the indexer SC decision was made; minted from the indexer's propagated logical timestamp.) Not used on indexer-SC: - marvin:shortCircuitedAgainstState -- compile-pipeline-only. IRI template: see Section L. Keyed on (work-slug, iso8601-instant) per DD-007's default rule; no compile-type variable because the indexer has none. Replay of the same indexer SC decision yields the same IRI by construction. See DD-014 for the B Q1 resolution (mint sibling vs reuse parent), DD-010 for the CorpusFileState chain this SC checks against, and #139 (Substream B of #123) for the implementation scope. The indexer-layer SC dispatcher implementation lives at marvin/pipeline/indexer/short_circuit.py. """@en-gb ; rdfs:subClassOf marvin:ShortCircuitDecision . # ========================================================================== # SECTION K -- Compile pipeline classes and taxonomies # ========================================================================== # PROV alignment (local assertion on externally-owned class) ies:Thing rdfs:subClassOf prov:Entity . # -------------------------------------------------------------------------- # K.1 marvin:CompiledDocument and state chain # -------------------------------------------------------------------------- marvin:CompiledDocument a rdfs:Class ; rdfs:label "Compiled Document"@en-gb ; dcterms:identifier "{6F7A8B9C-0D1E-4F6A-B3C4-5D6E7F8A9B0C}" ; rdfs:comment """An IndividualDocument produced by the Marvin compile pipeline. Artefact-layer; created and updated exclusively by the pipeline. The whole-life individual represents the document across all compile runs. Each compile run produces a new marvin:CompiledDocumentState (linked via ies:isStateOf) carrying the compile-type classification, checksums, and timestamp for that run. Successive states are linked via prov:wasRevisionOf (new state -> old state). Derivation from source is recorded on the CompiledDocumentState (not the whole-life document) using PROV sub-properties: - prov:hadPrimarySource -> CorpusFileState (for Summaries; v0.2.9 target; see DD-010 — pre-v0.2.9 the target was the whole-life CorpusFile) - prov:wasQuotedFrom -> source document (inline citations) - prov:wasDerivedFrom -> generic fallback Cross-links to other compiled documents use marvin:referencesDocument (peer navigational/citation links) or prov:wasDerivedFrom (derivation). """@en-gb ; rdfs:subClassOf ies:IndividualDocument, marvin:CompiledDocumentState . marvin:CompiledDocumentState a rdfs:Class ; rdfs:label "Compiled Document State"@en-gb ; dcterms:identifier "{7A8B9C0D-1E2F-4A7B-C4D5-6E7F8A9B0C1D}" ; rdfs:comment """A temporal state of a CompiledDocument representing a single compile run. Carries compile-type classification, marvin:sourceChecksumAtCompile (checksum of the input source(s) at compile time), marvin:checksumAtCompile (checksum of the output), marvin:ingestTimestamp (when the compile ran), and marvin:revisionNumber (the 1-indexed revision within the (work-slug, compile-type) scope, duplicating the {n} IRI variable as a SPARQL-aggregatable literal; see marvin:revisionNumber). The compile-type is asserted by typing the state as one of the ClassOfCompiledDocumentStateByCompileType instances (e.g. marvin:Summary, marvin:ConceptArticle). Successive states are linked by prov:wasRevisionOf: prov:wasRevisionOf . Canonical IES-native temporal bounding uses ies:BoundingState individuals linked via ies:isStartOf / ies:isEndOf and ies:inPeriod to ies:ParticularPeriod nodes. Pipeline invariant for successive states (state1 superseded by state2): a ies:BoundingState ; ies:isEndOf ; ies:inPeriod . # closes state1 a ies:BoundingState ; ies:isStartOf ; ies:inPeriod . # opens state2; SAME pp_T2 The shared ParticularPeriod node makes the boundary navigable as a graph pattern and enforces temporal continuity without date arithmetic. marvin:ingestTimestamp is retained as a convenience literal for staleness detection and pipeline logging, but it is NOT the canonical temporal bound. See DD-005 for the full worked example and Pattern A vs Pattern B rationale. """@en-gb ; ies:powertype marvin:ClassOfCompiledDocumentState ; rdfs:subClassOf ies:AssetState . marvin:ClassOfCompiledDocumentState a rdfs:Class ; rdfs:label "Class Of Compiled Document State"@en-gb ; dcterms:identifier "{8B9C0D1E-2F3A-4B8C-D5E6-7F8A9B0C1D2E}" ; rdfs:comment """The powertype of CompiledDocumentState. Taxonomy classes that classify compile-run states subclass this. Note: ies:ClassOfAssetState is not defined in IES Common v5; ies:ClassOfState is used as the parent. """@en-gb ; rdfs:subClassOf ies:ClassOfState . # -------------------------------------------------------------------------- # K.2 ClassOfCompiledDocumentStateByCompileType # # Data-level pattern: # <:mySummaryState> # a marvin:Summary ; # ies:isStateOf <:myDoc> ; # prov:hadPrimarySource <:corpusFileState> ; # marvin:sourceChecksumAtCompile "abc123" ; # marvin:checksumAtCompile "def456" ; # marvin:revisionNumber 1 ; # marvin:ingestTimestamp "2026-04-16T12:00:00Z"^^xsd:dateTimeStamp . # # BoundingState for temporal bounds (canonical IES-native pattern): # <:mySummaryState_start> a ies:BoundingState ; # ies:isStartOf <:mySummaryState> ; # ies:inPeriod <:pp_T1> . # -------------------------------------------------------------------------- marvin:ClassOfCompiledDocumentStateByCompileType a rdfs:Class ; rdfs:label "Class of Compiled Document State by Compile Type"@en-gb ; dcterms:identifier "{9C0D1E2F-3A4B-4C9D-E6F7-8A9B0C1D2E3F}" ; rdfs:comment """Controlled vocabulary classifying a CompiledDocumentState by the pipeline stage that produced it. Each entry types a marvin:CompiledDocumentState individual linked to the document via ies:isStateOf, enabling stage-specific queries and revision tracking. Compile type is a property of the state (not the whole-life document) to support prov:wasRevisionOf between successive compile runs and to allow (in principle) a document to change compile type across runs. Membership is closed. """@en-gb ; rdfs:subClassOf marvin:ClassOfCompiledDocumentState . marvin:Summary a marvin:ClassOfCompiledDocumentStateByCompileType ; rdfs:label "Compile Type: Summary"@en-gb ; dcterms:identifier "{0D1E2F3A-4B5C-4D0E-F7A8-9B0C1D2E3F4A}" ; rdfs:comment """A CompiledDocumentState produced by the Summarise stage. A lossy semantic compression of a single CorpusFile. Source linked via prov:hadPrimarySource on the state (target: marvin:CorpusFileState under DD-010 / v0.2.9). """@en-gb ; rdfs:subClassOf marvin:CompiledDocumentState . marvin:ConceptArticle a marvin:ClassOfCompiledDocumentStateByCompileType ; rdfs:label "Compile Type: Concept Article"@en-gb ; dcterms:identifier "{1E2F3A4B-5C6D-4E1F-A8B9-0C1D2E3F4A5B}" ; rdfs:comment """A CompiledDocumentState produced by the Categorise stage. A synthesised article covering a named concept, drawn from one or more Summary states. Sources linked via prov:wasDerivedFrom on the state; inline citations via marvin:referencesDocument. """@en-gb ; rdfs:subClassOf marvin:CompiledDocumentState . marvin:IndexDocument a marvin:ClassOfCompiledDocumentStateByCompileType ; rdfs:label "Compile Type: Index Document"@en-gb ; dcterms:identifier "{2F3A4B5C-6D7E-4F2A-B9C0-1D2E3F4A5B6C}" ; rdfs:comment """A CompiledDocumentState produced by the Index stage. A navigational directory of ConceptArticles and Summaries within a corpus. Constituent entries linked via marvin:referencesDocument. """@en-gb ; rdfs:subClassOf marvin:CompiledDocumentState . marvin:QARecord a marvin:ClassOfCompiledDocumentStateByCompileType ; rdfs:label "Compile Type: QA Record"@en-gb ; dcterms:identifier "{3A4B5C6D-7E8F-4A3B-C0D1-2E3F4A5B6C7D}" ; rdfs:comment """A CompiledDocumentState produced by a QASession in response to a DevelopmentQuestion. Carries the question, answer, and provenance links to sources (prov:hadPrimarySource, prov:wasQuotedFrom). If the answer commits to a design choice, the associated DevelopmentDecision links back via marvin:groundedIn. The DevelopmentQuestion is linked via marvin:answersQuestion (direction: DevelopmentQuestion -> QARecord). """@en-gb ; rdfs:subClassOf marvin:CompiledDocumentState . # -------------------------------------------------------------------------- # K.3 Datatype properties on CompiledDocumentState # -------------------------------------------------------------------------- marvin:sourceChecksumAtCompile a owl:DatatypeProperty ; rdfs:label "source checksum at compile"@en-gb ; dcterms:identifier "{4B5C6D7E-8F9A-4B4C-D1E2-3F4A5B6C7D8E}" ; rdfs:comment """SHA-256 checksum of the primary source input(s) at the time this compile state was produced. A CompiledDocumentState is stale when the marvin:fileChecksum on the latest marvin:CorpusFileState of the source CorpusFile differs from this value. Compare marvin:fileChecksum (on CorpusFileState; whole-life CorpusFile retains a literal under DD-010's dual-declaration default). """@en-gb ; rdfs:domain marvin:CompiledDocumentState ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . marvin:checksumAtCompile a owl:DatatypeProperty ; rdfs:label "checksum at compile"@en-gb ; dcterms:identifier "{5C6D7E8F-9A0B-4C5D-E2F3-4A5B6C7D8E9F}" ; rdfs:comment """SHA-256 checksum of the compiled output document at the time this compile state was produced. Detects post-hoc mutation of the output. Complements marvin:sourceChecksumAtCompile (which detects stale inputs) and marvin:fileChecksum (which covers raw CorpusFile content). """@en-gb ; rdfs:domain marvin:CompiledDocumentState ; rdfs:range xsd:string ; rdfs:subPropertyOf ies:attribute . # -------------------------------------------------------------------------- # K.4 marvin:ShortCircuitDecision # # Data-level pattern (short-circuit found the source unchanged, # pipeline emitted zero writes to CompiledDocumentState): # # <:shortCircuit_2026-04-22> # a marvin:ShortCircuitDecision ; # marvin:shortCircuitedAgainstFile <:corpusFileState> ; # marvin:shortCircuitedAgainstState <:prevSummaryState> ; # ies:inPeriod <:pp_2026-04-22T10:00:00Z> . # # The checksum value driving the short-circuit is recoverable as # ?sc marvin:shortCircuitedAgainstState/marvin:sourceChecksumAtCompile # without duplicating the literal on the event node. The logical # compile instant is carried by the ies:ParticularPeriod, minted with # the same {iso8601-instant} variable as compile-pipeline periods so # a short-circuit event and a parallel compile event in the same # pipeline invocation share period IRIs. # # v0.2.9 note. The marvin:shortCircuitedAgainstFile range was retyped # from marvin:CorpusFile (whole-life) to marvin:CorpusFileState # (temporal part) under DD-010 alongside the indexer-layer state-chain # introduction. The whole-life CorpusFile remains reachable from the # state via ies:isStateOf. # -------------------------------------------------------------------------- marvin:ShortCircuitDecision a rdfs:Class ; rdfs:label "Short-Circuit Decision"@en-gb ; dcterms:identifier "{6A7B8C9D-0E1F-4A2B-B3C4-D5E6F7A8B9C0}" ; rdfs:comment """An Event recording that the compile pipeline's source-content- hash short-circuit check determined no new compile run was required for a given (CorpusFile, compile-type) pair. Emitted in place of writes to the CompiledDocumentState chain when the source's current marvin:fileChecksum (on the latest marvin:CorpusFileState) equals the most recent CompiledDocumentState's marvin:sourceChecksumAtCompile, per DD-007's re-run-problem resolution as updated by DD-010 for the indexer-layer state-chain. Queryable provenance of non-writes, as required by Issue #29: an operator asking 'when did the pipeline last short-circuit this CorpusFile?' deserves a SPARQL answer, not a grep over log files. A marvin:ShortCircuitDecision is NOT a marvin:ValidationRun: no validation profile is executed, no ValidationCriterion passes or fails, and no CompiledDocumentState is produced or superseded. Reusing marvin:ValidationRun with a synthetic 'no-writes' result would overload its semantics; a dedicated class matches the IES idiom (distinct event types for distinct decisions) and keeps the validation-run query shape clean. Links: - marvin:shortCircuitedAgainstFile -> marvin:CorpusFileState (the temporal part of the source whose checksum was evaluated; the whole-life CorpusFile is reachable via ies:isStateOf. Range retyped from marvin:CorpusFile to marvin:CorpusFileState in v0.2.9 under DD-010.) - marvin:shortCircuitedAgainstState -> marvin:CompiledDocumentState (the most recent state found to already represent the current source; its marvin:sourceChecksumAtCompile equals the CorpusFileState's current checksum) - ies:inPeriod -> ies:ParticularPeriod (the logical instant at which the short-circuit decision was made; minted from the pipeline's propagated logical_timestamp so it shares IRIs with any parallel compile-event periods in the same pipeline invocation) IRI template: see Section L. Keyed on (work-slug, compile-type, iso8601-instant) per DD-007's default rule; replay of the same short-circuit decision yields the same IRI by construction. Indexer-layer SC. The parallel question of whether the indexer pipeline itself should short-circuit on unchanged on-disk bytes (avoiding gratuitous CorpusFileState mints) is resolved under DD-014 (v0.2.12, B Q1 of [#139](https://github.com/aigora-de/marvin/issues/139) / Substream B of [#123](https://github.com/aigora-de/marvin/issues/123)): the indexer-SC class is the sibling marvin:IndexerShortCircuitDecision (declared in Section J), an rdfs:subClassOf of this class. The indexer-SC sibling uses marvin:shortCircuitedAgainstFile only; the marvin:shortCircuitedAgainstState predicate above remains compile-pipeline-specific (its range marvin:CompiledDocumentState has no indexer analogue, so no range widening is required). See Issue #29 (compile pipeline implementation) and DD-007 Consequences 'Short-circuit logging' for the original rationale, DD-010 for the v0.2.9 range update on marvin:shortCircuitedAgainstFile, and DD-014 for the indexer-SC sibling-class resolution. """@en-gb ; rdfs:subClassOf ies:Event . # ========================================================================== # SECTION L -- IRI template assertions (DD-007) # ========================================================================== # # Each pipeline-written state node type carries a marvin:iriTemplate # declaring the deterministic IRI scheme for instances of that type. # Templates are transparent composites of the node's logical-identity # tuple; variables in {curly braces} are substituted by pipeline code # at mint time from the tuple values. See DD-007 for the full scheme, # the rejected alternatives, and the resolution of the re-run problem # via source-content-hash comparison at pipeline entry. # # Templates are asserted on Marvin-defined classes and — following the # Section K precedent for ies:Thing rdfs:subClassOf prov:Entity — on # externally-owned IES classes used by Marvin pipelines (ies:BoundingState, # ies:ParticularPeriod). Each such external assertion is flagged as a # local assertion on an externally-owned class. # # Variable semantics: # # {work-slug} # The marvin:workSlug of the artefact-layer ies:WorkOfDocumentation # identified by the IRI being minted. For compile-pipeline state # nodes (marvin:CompiledDocument, marvin:CompiledDocumentState, # marvin:ShortCircuitDecision) this is the WorkOfDocumentation # linked via ies:aCopyOf from the marvin:CorpusFile being compiled. # For the indexer/artefact-layer corpus templates added by Issue # #86 (marvin:CorpusFile and ies:WorkOfDocumentation), the # resolution is one step shorter: {work-slug} is the # marvin:workSlug of the WorkOfDocumentation itself (in the # ies:WorkOfDocumentation template) or of the WorkOfDocumentation # that the CorpusFile is ies:aCopyOf (in the marvin:CorpusFile # template). Format: ^[a-z][a-z0-9-]{2,63}$. Stable across file # renames and byte-level source changes. CI-enforced for presence, # format, and uniqueness. See marvin:workSlug definition (Section J). # # {copy-discriminator} # A kebab-case ASCII identifier disambiguating one upstream copy of # a ies:WorkOfDocumentation from another, used in the # ies:IndividualDocument upstream-anchor template (DD-011, v0.2.9). # # Derivation rule (named under # [#141](https://github.com/aigora-de/marvin/issues/141), Substream # D of [#123](https://github.com/aigora-de/marvin/issues/123)). The # discriminator is the `upstream_source_id` field declared in the # indexer's replication configuration at # `marvin/pipeline/indexer/replication.yaml`, for the per-CorpusFile # entry keyed by work_slug. Discriminators are NOT derived from # filesystem paths or other unstable inputs; the config file is the # authoritative source. Renames or relocations of the upstream copy # on disk do not churn the discriminator. The config file is the # replication-edge configuration surface settled at [#141](https://github.com/aigora-de/marvin/issues/141) # panel-at-PR-open (D Q1). # # Pattern parallel: this is the same operator-chosen-then- # immortalised-in-IRI shape that marvin:workSlug carries for # `corpus-file/{work-slug}` and `work-of-documentation/{work-slug}` # (Issue #86 extension of DD-007). The discriminator inherits # that stability discipline: operator-named, format-constrained, # change-is-deliberate. Not a new pattern at the schema layer. # # Three invariants: # - Determinism: the same upstream copy under a fixed config # yields the same discriminator across re-mints. The # worked-example replay (top-level [#123](https://github.com/aigora-de/marvin/issues/123) # acceptance) depends on this. # - Distinguishability: the upstream-anchor template's path # segment `upstream-anchor/` differs from `corpus-file/`, so # no upstream-anchor IRI can pattern-collide with a CorpusFile # IRI. The format-side invariant on both path segments is # enforced by check-upstream-anchor-iri-format.rq. # - Stability: the discriminator is config-declared, not # filesystem-derived. A renamed upstream file on disk does not # require an upstream-anchor re-mint; the discriminator stays # whatever the config file names. Operators changing the # discriminator in config do so deliberately and accept the # IRI churn. # # Multi-copy disposition. Unlike marvin:CorpusFile (one canonical # copy per Work in a given corpus, no copy-discriminator), the # upstream-anchor template explicitly accommodates multiple # upstream copies of the same Work — hence the variable. A # marvin:CorpusFile in the Marvin corpus that replicates from one # upstream copy and a hypothetical sibling CorpusFile replicating # from a different upstream copy would point at distinct # upstream-anchors under this template. Multi-copy CorpusFile # semantics themselves remain deferred per the marvin:CorpusFile # template note below; [#141](https://github.com/aigora-de/marvin/issues/141) # covers upstream-anchors only. # # Format and CI. Format constraint mirrors the {work-slug} format # (^[a-z][a-z0-9-]{2,63}$). Enforcement of the format on # upstream-anchor IRIs is check-upstream-anchor-iri-format.rq # (added under [#141](https://github.com/aigora-de/marvin/issues/141)); # ABox check queued for [#60](https://github.com/aigora-de/marvin/issues/60)'s # `marvin validate`, not CI, per the ABox-checks-policy that # [#117](https://github.com/aigora-de/marvin/issues/117) Phase 2 # panel B1 settled. The [#117](https://github.com/aigora-de/marvin/issues/117) # Phase 2 PR minted the worked-example's single upstream-anchor # (`extending-ies` → `ies-source`) editorially under what Section # 19.1 called "Option A"; the named convention formalised here is # consistent with that choice — no IRI re-mint, and the # replication-config entry for the worked example is the canonical # example in `marvin/pipeline/indexer/replication.yaml`. # # {slug} # A stable, human-chosen identifier for a marvin:OpenTension, # used in the OpenTension and OpenTensionState IRI templates # (DD-012, v0.2.11). The variable carries the identity-bearing # slug body — kebab-case ASCII — without any namespace-specific # prefix used in the project-level or worked-example-namespaced # short forms (project-level: no prefix; worked-example `we:` # form: `tension-` for whole-life, `ots-` for state). # # Format: ^[a-z][a-z0-9-]{2,63}$ — kebab-case ASCII, starting # with a letter, length 3–64 characters (matching # marvin:workSlug's format constraint, since both serve the same # DD-007 stable-identifier-anchor role for their respective node # types). # # Naming-form parallelism. The same {slug} body underlies both # IRI forms an OpenTension may take. For the compile-pipeline # powertype-pattern worked example's `we:tension-derivedfrom- # target-convention`, the body is `derivedfrom-target- # convention`; the project-level template would mint it as # `https://w3id.org/marvin/open-tension/derivedfrom-target- # convention`. The two forms are alternatives for the same # logical OpenTension under their respective namespace # conventions, not parallel IRIs for the same RDF resource. # # Project-level mints use the Section L template literally, # producing IRIs under `https://w3id.org/marvin/open-tension/` # (whole-life) and `https://w3id.org/marvin/open-tension-state/` # (state). Worked-example mints use the worked-example's `we:` # prefix with `tension-` / `ots-` short-form prefixes per the # established worked-example-namespacing convention; see the # Section L template-block prose above for the two-form # parallel-shape note. # # Distinct from marvin:workSlug (which identifies a # ies:WorkOfDocumentation) and from marvin:artefactSlug (which # identifies a marvin:OntologyArtefact via the upstream IES # IRI). The three slug variables share a DD-007 stability # discipline but identify different node types; they are not # interchangeable. # # CI enforcement. Format and uniqueness within the OpenTension # instance set are not CI-enforced at v0.2.11. The # [#94](https://github.com/aigora-de/marvin/issues/94) Phase 2 PR # mints OpenTension slugs editorially (four existing slug bodies # in the compile-pipeline powertype-pattern worked example: # `derivedfrom-target-convention`, # `corpus-file-lifecycle`, # `corpus-replication-lineage`, # `cq-validation-run-shape`); format is enforced by reviewer # scrutiny in that PR rather than by an automated check. A # future SHACL shape or SPARQL ASK on slug format would land # under [#116](https://github.com/aigora-de/marvin/issues/116) by # analogy to the marvin:workSlug enforcement set. # # {compile-type} # A short kebab-case form of the ClassOfCompiledDocumentStateByCompileType # instance (e.g. "summary", "concept-article", "index-document", # "qa-record"). Resolved by pipeline code from the state's # rdf:type that is an instance of that ClassOfElement. # # {n} # 1-indexed revision number within the bearing class's logical # scope. Computed at mint time as 1 + MAX(existing n) or 1 if none. # The read-before-mint is re-entrant under pyoxigraph's # repeatable-read isolation (DD-006); the pipeline serialises # writes per scope-tuple. The value is also written as a # marvin:revisionNumber literal on the bearing state node so # SPARQL aggregates can operate without parsing the IRI path. # # Scope per bearing class: # - marvin:CompiledDocumentState — (work-slug, compile-type) # - marvin:CorpusFileState — (work-slug). One state-stream # per CorpusFile per Work; multi-copy is out of scope per # the marvin:CorpusFile template note below. # # {state-local-id} # A composite identifier that uniquely identifies the bounded # state within the BoundingState namespace. Composed as the # ``--``-joined concatenation of the bounded state's IRI's # identity-bearing trailing path segments. The segment count is # determined by the bounded state's own template: # # Sync pipeline state IRI: # .../{artefact-slug}/rev-{n} # -> local id: # {artefact-slug}--rev-{n} # # Compile pipeline state IRI: # .../{work-slug}/{compile-type}/rev-{n} # -> local id: # {work-slug}--{compile-type}--rev-{n} # # Indexer pipeline state IRI (added by DD-010, v0.2.9): # .../{work-slug}/rev-{n} # -> local id: # {work-slug}--rev-{n} # # The /start and /end suffixes in BoundingState templates # disambiguate the two bounds of a single state. # # Issue #87 amended this rule. Earlier versions of the schema # described the local id as the single last path segment; both # pipelines have always collapsed multiple trailing segments, # and the compile pipeline must collapse three to disambiguate # across distinct works at the same (compile-type, n). Pre-fix # compile-pipeline BoundingState IRIs collided across works # under RDF set-semantics, collapsing distinct boundary events # into a single node. # # {iso8601-instant} # The xsd:dateTimeStamp representation of the logical compile # instant, URI-escaped. Two distinct logical instants produce # distinct periods; the same logical instant (the shared period at # a revision boundary) produces the same period IRI referenced by # both the closing and opening BoundingState. The logical instant # is propagated through the pipeline from the point at which the # source-content-hash comparison determined a write was required; # it is NOT the wall-clock instant of node construction. # # {artefact-slug} # The marvin:artefactSlug (Section J) of a marvin:OntologyArtefact. # Format: ^[a-z][a-z0-9-]{2,127}$. Machine-derived from the source # IES IRI as "{module-slug}--{kebab-cased-local-name}". See the # marvin:artefactSlug definition for the derivation rule and its # relationship to marvin:workSlug (same DD-007 stability rule, # upstream-maintained identifier rather than human-maintained one). # # {subject-slug}, {object-slug} # The marvin:artefactSlug of the marvin:ClassNode or # marvin:PropertyNode the corresponding endpoint of an axiom triple # refers to. Resolution rule (per Issue #53): looked up in the # current sync pass first, then in the existence layer for prior- # pass artefacts; if neither resolves, the sync pass is refused # before any commit_atomic call (cross-module reference resolution). # Note: {subject-slug} also appears in the marvin:ValidationRun # template, where it identifies the artefact being validated # (typically a work slug or artefact slug); the local context of # each template determines its resolution rule. # # {predicate-local} # The local-name portion of an axiom predicate's IRI (post-'#' if a # fragment, post-last-'/' otherwise), lower-cased and converted from # camelCase to kebab-case. Examples: rdfs:subClassOf -> sub-class-of, # rdfs:subPropertyOf -> sub-property-of, rdfs:domain -> domain, # rdfs:range -> range. Future axiom predicates (e.g. # owl:equivalentClass -> equivalent-class) follow the same rule. # # {dd-number} # The zero-padded DD number of the DevelopmentDecision, e.g. # "dd-007". Already a stable, maintained slug by project convention. # # {profile-id}, {profile-version} # The stable identifier and version of the ValidationProfile. # # {validation-logical-timestamp} # The xsd:dateTimeStamp of the logical validation instant, # propagated through the validation pipeline analogously to # {iso8601-instant}. # # {criterion-id} # The stable identifier of a marvin:ValidationCriterion within its # profile (the criterion's slug, kebab-case ASCII). Distinguishes the # per-criterion marvin:CriterionResult IRIs minted under one # marvin:ValidationRun. Added v0.2.13 per DD-015. marvin:CompiledDocument marvin:iriTemplate "https://w3id.org/marvin/compiled-document/{work-slug}" . marvin:CompiledDocumentState marvin:iriTemplate "https://w3id.org/marvin/compiled-document-state/{work-slug}/{compile-type}/rev-{n}" . marvin:OntologyArtefactState marvin:iriTemplate "https://w3id.org/marvin/ontology-artefact-state/{artefact-slug}/rev-{n}" . marvin:DevelopmentDecisionState marvin:iriTemplate "https://w3id.org/marvin/development-decision-state/{dd-number}/rev-{n}" . marvin:ValidationRun marvin:iriTemplate "https://w3id.org/marvin/validation-run/{subject-slug}/{profile-id}/{profile-version}/{validation-logical-timestamp}" . marvin:CriterionResult marvin:iriTemplate "https://w3id.org/marvin/criterion-result/{subject-slug}/{profile-id}/{profile-version}/{validation-logical-timestamp}/{criterion-id}" . # Existence-layer artefact templates (added by Issue #53). # All five are logical-composite over {artefact-slug} per DD-007's # default rule. The artefactSlug derivation already encodes module # membership ({module-slug}--{kebab-cased-local-name}), so layer- and # module-level slugs collide-free with class/property/namespace slugs # in the same module by construction. marvin:ClassNode marvin:iriTemplate "https://w3id.org/marvin/class-node/{artefact-slug}" . marvin:PropertyNode marvin:iriTemplate "https://w3id.org/marvin/property-node/{artefact-slug}" . marvin:NamespaceNode marvin:iriTemplate "https://w3id.org/marvin/namespace-node/{artefact-slug}" . marvin:OntologyModule marvin:iriTemplate "https://w3id.org/marvin/ontology-module/{artefact-slug}" . marvin:OntologyLayer marvin:iriTemplate "https://w3id.org/marvin/ontology-layer/{artefact-slug}" . # Indexer/artefact-layer corpus templates (added by Issue #86). # DD-007's original scope (Issue #31) excluded marvin:CorpusFile, # treating it as identified by external conventions (filePath). Issue # #86 extends DD-007's default rule to marvin:CorpusFile and to its # artefact-layer counterpart ies:WorkOfDocumentation, anchoring both # on marvin:workSlug rather than on the churnable filePath. This is # the same logical-composite-over-{work-slug} shape already used for # marvin:CompiledDocument; it formalises the IRI shape that #84 Stage # 1 commits under the default rule, and reverts marvin:filePath from # an implicit identifier component to a property of the CorpusFile. # See DD-007 Status updates (2026-04-29) for the carve-out amendment. # # The CorpusFile template assumes a single canonical CorpusFile per # Work in a given corpus, matching the schema's current working # assumption (see marvin:CorpusFile in Section J). Multi-copy # semantics would require a richer template with a copy-discriminator # variable and is out of scope for #86 — it is a separable change at # the time multi-copy is genuinely needed, affecting the indexer's # CorpusFile IRIs only (the WorkOfDocumentation template is unaffected # by multi-copy and would not need to change). The # ies:WorkOfDocumentation template itself is asserted below alongside # the other externally-owned IES classes, following the # 'local assertion on externally-owned class' precedent. marvin:CorpusFile marvin:iriTemplate "https://w3id.org/marvin/corpus-file/{work-slug}" . # Indexer-layer state-chain template (added by DD-010, v0.2.9). # Logical-composite over (work-slug, n) per DD-007's default rule. # One stream of states per CorpusFile (one per ingest event); no # compile-type analogue is required at the indexer layer. Re-ingest # of unchanged content is handled by the indexer-layer SC question # scoped to [#123](https://github.com/aigora-de/marvin/issues/123), # not by minting a new state. marvin:CorpusFileState marvin:iriTemplate "https://w3id.org/marvin/corpus-file-state/{work-slug}/rev-{n}" . # AxiomNode IRI scheme: logical-composite over the SPO triple, staying # inside DD-007's default rule. The content-hash variant (DD-007's # 'immutable-content escape hatch') was considered and rejected during # Issue #53 scoping; the SPO-composite trades a longer IRI for # greppability and IRI-body debuggability. See Issue #53 for the full # rationale. AxiomNode does NOT carry marvin:artefactSlug — its identity # is its (subject, predicate, object) triple, expressed directly in # its IRI. marvin:AxiomNode marvin:iriTemplate "https://w3id.org/marvin/axiom-node/{subject-slug}/{predicate-local}/{object-slug}" . # ShortCircuitDecision IRI scheme (added by Issue #29). Logical-composite # over (work-slug, compile-type, iso8601-instant) per DD-007's default # rule. Replay of the same short-circuit decision — same corpus file, # same compile type, same propagated logical timestamp — yields the same # IRI by construction. See marvin:ShortCircuitDecision (Section K.4). marvin:ShortCircuitDecision marvin:iriTemplate "https://w3id.org/marvin/short-circuit-decision/{work-slug}/{compile-type}/{iso8601-instant}" . # IndexerShortCircuitDecision IRI scheme (added by DD-014, v0.2.12). # Logical-composite over (work-slug, iso8601-instant) per DD-007's # default rule. No {compile-type} variable -- the indexer has no # compile-type analogue (it operates on the raw CorpusFile, not a # compile-pipeline output). Replay of the same indexer SC decision -- # same corpus file, same propagated logical timestamp -- yields the # same IRI by construction. # # Distinguishability from marvin:ShortCircuitDecision IRIs is structural: # the compile-SC template has three path segments after the class prefix # ({work-slug}/{compile-type}/{iso8601-instant}); the indexer-SC template # has two ({work-slug}/{iso8601-instant}). The class-prefix path segment # itself differs (short-circuit-decision/ vs indexer-short-circuit-decision/), # so no compile-SC IRI can pattern-match an indexer-SC IRI and vice versa. # See marvin:IndexerShortCircuitDecision (Section J.x) and DD-014 for # the B Q1 sibling-mint resolution. marvin:IndexerShortCircuitDecision marvin:iriTemplate "https://w3id.org/marvin/indexer-short-circuit-decision/{work-slug}/{iso8601-instant}" . # Local assertions on externally-owned classes (see Section K precedent # for ies:Thing rdfs:subClassOf prov:Entity). # ies:BoundingState has two template variants distinguished by the # /start vs /end suffix. Pipeline code selects the correct template # based on whether the bound is an opening (ies:isStartOf) or closing # (ies:isEndOf) bound. Both templates are declared on the same class; # this is the one case in the current set where a class has more than # one template, and is the motivating example for why templates are # rdfs:Class-to-xsd:string rather than single-valued. ies:BoundingState marvin:iriTemplate "https://w3id.org/marvin/bounding-state/{state-local-id}/start" , "https://w3id.org/marvin/bounding-state/{state-local-id}/end" . ies:ParticularPeriod marvin:iriTemplate "https://w3id.org/marvin/particular-period/{iso8601-instant}" . # ies:WorkOfDocumentation IRI scheme (added by Issue #86, paired with # the marvin:CorpusFile template above). Logical-composite over a # single {work-slug} per DD-007's default rule, anchored on # marvin:workSlug — declared on this class in Section J — which is # the maintained, stable, human-chosen identifier of the work. The # slug is identity-bearing on the WorkOfDocumentation directly: an # ies:aCopyOf hop is not required to resolve {work-slug} for instances # of this class. Multi-copy scenarios (multiple CorpusFile copies of # the same WorkOfDocumentation) do not affect this template's shape. ies:WorkOfDocumentation marvin:iriTemplate "https://w3id.org/marvin/work-of-documentation/{work-slug}" . # ies:IndividualDocument upstream-anchor template (added by DD-011, # v0.2.9). Logical-composite over ({work-slug}, {copy-discriminator}) # per DD-007's default rule. The upstream-anchor is a non-tracked # structural placeholder for an upstream copy of a Work that a # marvin:CorpusFile in the Marvin corpus has been replicated from # (see marvin:replicatedFrom in Section F). Multiple upstream copies # of the same Work may exist, hence the {copy-discriminator}; the # template path uses 'upstream-anchor' as a fixed segment to make the # IRI's role legible in greppable form. # # Scope of this template. ies:IndividualDocument is externally-owned # (declared in IES Common); this template applies only to instances # of the class minted by Marvin pipelines or editorial processes as # upstream-anchors. Other ies:IndividualDocument instances in the # Marvin Memory Graph (e.g. marvin:CorpusFile instances, which are # rdfs:subClassOf ies:IndividualDocument) carry their own templates # under their more specific class — the template here is reached # only when the bare ies:IndividualDocument class is the most # specific applicable type and the instance is being minted as an # upstream-anchor. Pipeline code must not apply this template to # arbitrary IndividualDocument instances; the indexer's replication # configuration at `marvin/pipeline/indexer/replication.yaml` is the # source of truth for which CorpusFiles are replications and which # upstream-anchors to mint — see the {copy-discriminator} variable- # semantics block above and DD-011 for the full derivation rule # named under [#141](https://github.com/aigora-de/marvin/issues/141). ies:IndividualDocument marvin:iriTemplate "https://w3id.org/marvin/upstream-anchor/{work-slug}/{copy-discriminator}" . # OpenTension whole-life and state templates (added by DD-012, v0.2.11). # # Two-form discipline. Section L's templates for OpenTension and # OpenTensionState declare the project-level canonical IRI shape # under the `https://w3id.org/marvin/` namespace. Worked-example # OpenTensions and their state-chains have historically been minted # under their worked-example-specific namespaces (e.g. the # `compile-pipeline-powertype-pattern` worked example's `we:` # prefix at `https://w3id.org/marvin/worked-example/ # compile-pipeline-powertype-pattern/`); this convention is # preserved under DD-012 by a parallel `we:`-form shape that # the worked example's ledger uses. The two forms are: # # Project-level (this template): # marvin:OpenTension open-tension/{slug} # marvin:OpenTensionState open-tension-state/{slug}/rev-{n} # # Worked-example-namespaced (ledger convention, not a Section L # template — declared here as a stylistic note for orientation): # marvin:OpenTension we:tension-{slug} # marvin:OpenTensionState we:ots-{slug}-rev-{n} # # The two forms agree on what {slug} carries (the identity-bearing # slug body without the `tension-`/`ots-` prefixes; see Section L's # {slug} variable-semantics entry) and on the revision-counter # semantics; they differ in path-segment shape because the `we:` # prefix is a stylistic short form for worked-example artefacts, # not a path-segmented project-level mint. The worked example's # DD/RejectedAlternative/session naming follows the same parallel- # form convention (we:dd-we-g-NNN, we:rej-we-g-NNN-slug, # we:session-gN), so the OpenTension state-chain extending it is # consistent with the worked example's established naming. # # Section L's template applies literally to project-level OpenTension # mints (e.g. tensions surfaced in non-worked-example code, in # core schema development, in the validation pipeline's design # discussions). The worked example's pre-DD-012 OpenTensions and # their DD-012-Phase-2 state-chains stay in `we:`-form per the # worked-example-namespacing convention; this is consistent with # the worked example's `marvin:DevelopmentDecision` instances # (we:dd-we-g-NNN) also not appearing under any # development-decision-state/* path. # # The state template is logical-composite over {slug} and {n} per # DD-007's default rule, with the read-before-mint discipline # shared with marvin:CompiledDocumentState (DD-005) and # marvin:CorpusFileState (DD-010). Integer counter (not scope- # narration-hash) per DD-012 Q2 Decision rationale. # # Multi-copy disposition. One state-stream per OpenTension; no # discriminator beyond {slug} is needed. If a future need arises # for two OpenTensions with the same slug body, the second would # carry a discriminator suffix in its slug body — a slug-level # convention, not a template change. # # Section-L {state-local-id} composition for project-level # OpenTensionState BoundingStates follows the existing post-DD-010 # rule for two-trailing-segment indexer-shape templates: # # OpenTensionState IRI: # .../{slug}/rev-{n} # -> local id: # {slug}--rev-{n} # # matching the marvin:CorpusFileState case exactly. Worked-example- # namespaced OpenTensionState mints do not pass through this # template; their BoundingStates are minted in the worked example's # `we:` namespace too, with a `we:` local-id form # (e.g. we:ots-{slug}-rev-{n}-start / -end). See the worked # example's ledger Section 21 for the empirical shape. # # The /start and /end suffixes on BoundingState IRIs (in both # forms) disambiguate the two bounds of a single state. R3 # (partial-narrowing) states have no closing bound, so only the # /start variant is minted for those. # # See DD-012 § Consequences for the full schema-mutation scope and # § The shape illustrated for worked-example IRIs in the `we:` # form. marvin:OpenTension marvin:iriTemplate "https://w3id.org/marvin/open-tension/{slug}" . marvin:OpenTensionState marvin:iriTemplate "https://w3id.org/marvin/open-tension-state/{slug}/rev-{n}" .