Skip to content

domain-story

Top-level Domain Storytelling document. A story is a numbered sequence of sentences that describe one narrative flow through the domain.

Schema

type: object
properties:
    apiVersion:
        const: schema.esdm.io/domain-storytelling/v1
    kind:
        const: domain-story
    name:
        type: string
        pattern: "^[a-z][a-z0-9-]*$"
    description:
        type: string
    metadata:
        type: object
        properties:
            labels:
                type: object
                additionalProperties:
                    type: string
            annotations:
                type: object
                additionalProperties:
                    type: string
        additionalProperties: false
    scope:
        type: object
        properties:
            domain:
                type: string
                pattern: "^[a-z][a-z0-9-]*$"
        required: [domain]
        additionalProperties: false
    pointInTime:
        type: string
        enum: [as-is, to-be]
    granularity:
        type: string
        enum: [coarse-grained, fine-grained]
    domainPurity:
        type: string
        enum: [pure, digitalized]
    groups:
        type: array
        minItems: 1
        items:
            type: object
            properties:
                name:
                    type: string
                    pattern: "^[a-z][a-z0-9-]*$"
                description:
                    type: string
                annotation:
                    type: string
            required: [name]
            additionalProperties: false
    actors:
        type: array
        minItems: 1
        items:
            type: object
            properties:
                name:
                    type: string
                    pattern: "^[a-z][a-z0-9-]*$"
                annotation:
                    type: string
                groups:
                    type: array
                    minItems: 1
                    items:
                        type: string
                        pattern: "^[a-z][a-z0-9-]*$"
            required: [name]
            additionalProperties: false
    sentences:
        type: array
        minItems: 1
        items:
            type: object
            properties:
                sequenceNumber:
                    type: integer
                    minimum: 1
                workObjects:
                    type: array
                    minItems: 1
                    items:
                        type: object
                        properties:
                            name:
                                type: string
                                pattern: "^[a-z][a-z0-9-]*$"
                            annotation:
                                type: string
                            groups:
                                type: array
                                minItems: 1
                                items:
                                    type: string
                                    pattern: "^[a-z][a-z0-9-]*$"
                        required: [name]
                        additionalProperties: false
                edges:
                    type: array
                    minItems: 1
                    items:
                        type: object
                        properties:
                            from:
                                oneOf:
                                    - type: object
                                      properties:
                                        actor:
                                            type: string
                                            pattern: "^[a-z][a-z0-9-]*$"
                                      required: [actor]
                                      additionalProperties: false
                                    - type: object
                                      properties:
                                        workObject:
                                            type: string
                                            pattern: "^[a-z][a-z0-9-]*$"
                                      required: [workObject]
                                      additionalProperties: false
                            to:
                                oneOf:
                                    - type: object
                                      properties:
                                        actor:
                                            type: string
                                            pattern: "^[a-z][a-z0-9-]*$"
                                      required: [actor]
                                      additionalProperties: false
                                    - type: object
                                      properties:
                                        workObject:
                                            type: string
                                            pattern: "^[a-z][a-z0-9-]*$"
                                      required: [workObject]
                                      additionalProperties: false
                            label:
                                type: string
                            annotation:
                                type: string
                            groups:
                                type: array
                                minItems: 1
                                items:
                                    type: string
                                    pattern: "^[a-z][a-z0-9-]*$"
                        required: [from, to]
                        additionalProperties: false
            required: [sequenceNumber, edges]
            additionalProperties: false
required: [apiVersion, kind, name, scope, sentences]
unevaluatedProperties: false

Anatomy

A Domain Story scopes to a Domain via scope.domain. Stories are not bound to a single Bounded Context because a narrative often crosses contexts – an invitation drafted in one and accepted in another, for instance.

Three optional classifiers position the story in the broader landscape. pointInTime carries as-is or to-be, distinguishing a description of current behavior from a target picture. granularity carries coarse-grained or fine-grained, signaling how zoomed-in the narrative is. domainPurity carries pure or digitalized, separating a story about humans-and-paper from a story about how the digital system supports them. All three are non-binding for the linter; they document intent for the reader.

The optional groups array declares groups that nodes and edges can belong to. Each group carries a required name, plus optional description and annotation. The description is prose; the annotation is in-diagram text shown alongside the group when rendered. The list must be non-empty when present, with at least one group.

The optional actors array declares story-global Actors. Bare Actors can be referenced inline from edges without a declaration, so this list is required only for Actors that need to carry an annotation or groups membership – metadata that has no place to live on a bare inline reference. Each entry carries a required name, an optional annotation, and an optional groups list naming the groups the Actor belongs to. The groups list, when present, must be non-empty.

The required sentences array carries the narrative itself, with at least one entry. Each sentence has a required sequenceNumber (an integer of at least one), a required edges array, and an optional workObjects array. Duplicate sequenceNumber values denote parallel sentences at the same position – two things happening simultaneously in the narrative.

The per-sentence workObjects list declares Work Objects that need an annotation or groups membership. As with Actors, bare Work Objects can be referenced inline from edges without declaration, so the list is required only when there is something to say beyond the name. Each entry carries a required name, an optional annotation, and an optional non-empty groups list. The same name in a different sentence is a new instance with its own annotation, because Domain Storytelling redraws Work Objects per sentence.

The per-sentence edges list is required and non-empty. Each edge carries a required from node reference, a required to node reference, an optional label (the Activity text – verb, preposition, or conjunction), an optional annotation, and an optional non-empty groups list. A node reference is { actor: <name> } or { workObject: <name> }; mixing both shapes within one reference is rejected.

The annotation field on Actors, Work Objects, and edges is distinct from metadata.annotations: it carries in-diagram text, while metadata.annotations is for tooling and provenance.

The common document-level fields complete the picture: apiVersion is schema.esdm.io/domain-storytelling/v1, kind is domain-story, name is the story's kebab-case identifier, description carries free-form prose, and metadata holds non-semantic labels and annotations.