workflow vis-coauthorship-community-evolution
  template: define-unit -> characterise ->
            loop(define-unit (windows/communities) -> characterise (flow) ->
                 contextualise -> visualise -> abstract (events) -> assess ->
                 generate-knowledge (evolution) ->
                 characterise (author metrics) -> define-unit (roles) -> visualise ->
                 abstract (stability) -> generate-knowledge (stability) ->
                 characterise (text) -> build-model (topics) -> visualise ->
                 characterise (topic profiles) -> visualise (topic evolution) ->
                 abstract (foci) -> generate-knowledge (foci) ->
                 characterise (overlap) -> visualise (overlap) -> abstract (overlap) ->
                 assess (integration)) ->
            generate-knowledge (integrated synthesis)
  description: "Visual analytics workflow for identifying and characterising the
    intellectual communities of the IEEE VIS co-authorship network, tracking
    core stability, membership drift, merge/split/dissolution events, and
    associated research foci across 1990-2024, with an outer refinement loop
    allowing foundational community-detection choices to be revisited in light
    of downstream role, topic, and overlap findings"

# ============================================================================
# INPUT
# ============================================================================

artifact D_papers : entities
  origin: given
  internal structure: elementary
  embedment: {set, time}
  features:
    - id: f_authors
      value structure: list
      value type: reference
      description: "Disambiguated author IDs"
    - id: f_year
      value structure: atomic
      value type: temporal
    - id: f_title
      value structure: atomic
      value type: text
    - id: f_abstract
      value structure: atomic
      value type: text
    - id: f_keywords
      value structure: list
      value type: text
    - id: f_citations
      value structure: list
      value type: reference
      description: "Citation links (provided but not used in this workflow)"
  description: "3596 IEEE VIS papers (Vis/InfoVis/VAST/SciVis), 1990-2024"

# ============================================================================
# PHASE 0: DEFINE AUTHORS AND FULL-PERIOD CO-AUTHORSHIP NETWORK
# ============================================================================

transform T_define_authors :
  intent: define-unit
  manner: "extract"
  input: D_papers
  output: D_authors
  actor: machine
  description: "Extract distinct disambiguated authors as analysis units"

artifact D_authors : entities
  internal structure: elementary
  embedment: {time, relational structure}
  features:
    - id: f_active_years
      value structure: list
      value type: temporal
  description: "Distinct disambiguated authors, situated in publication time
    and in the co-authorship network"

transform T_char_coauthor_full :
  intent: characterise
  manner: "define-relations (co-authorship, full period)"
  input: D_authors, D_papers
  output: F_coauthor_full
  actor: machine
  description: "Compute weighted co-authorship relation across the full
    1990-2024 period"

artifact F_coauthor_full : feature(D_authors)
  value structure: relational configuration
  value type: numeric
  representation form: "weighted co-authorship graph, full period (anchor structure)"

# ============================================================================
# SPECIFICATIONS AND PROVENANCE LOG (given at start; consumed/updated throughout)
# ============================================================================

artifact S_detection_spec : specification
  origin: given
  representation form: "parameter settings (window length, window step,
    community-detection algorithm and resolution)"
  description: "Initial choices governing temporal windowing and
    community-detection granularity"

artifact S_role_thresholds : specification
  origin: given
  representation form: "parameter settings (tenure and centrality thresholds)"
  description: "Initial thresholds defining what counts as high tenure, high
    centrality, and multi-community (boundary-spanning) membership"

artifact S_overlap_threshold : specification
  origin: given
  representation form: "parameter settings (overlap-weight threshold)"
  description: "Initial threshold defining what counts as a persistently
    high-overlap community pair"

artifact S_topic_spec : specification
  origin: given
  representation form: "parameter settings (number of topics, seed terms)"
  description: "Initial topic-model configuration"

artifact K_provenance_log : knowledge(S_detection_spec, S_topic_spec,
    S_role_thresholds, S_overlap_threshold)
  origin: given
  representation form: "chronological log of specification changes"
  description: "Initially empty; accumulates a record of each change made to
    S_detection_spec, S_topic_spec, S_role_thresholds, or S_overlap_threshold
    during iterative refinement, so revisions can be compared to earlier ones"

# ============================================================================
# OUTER LOOP: INTEGRATED REFINEMENT ACROSS ALL DOWNSTREAM PHASES
# ============================================================================

loop L_integrated_analysis:
  purpose: "Ensure that community structure, core stability, research foci,
    and cross-community overlap together form a coherent account of the VIS
    intellectual structure; allow foundational temporal-windowing and
    community-detection choices to be revisited in light of downstream
    role, topic, or overlap findings, not only in light of the community
    partition itself"
  until: "The combined characterisation of communities, their evolution
    events, core stability/leadership, research foci, and overlap patterns
    is judged coherent and consistent with domain knowledge of the VIS
    community"
  body:

    # ------------------------------------------------------------------------
    # PHASE 3 (INNER LOOP): WINDOWING, COMMUNITY DETECTION, CROSS-TIME MATCHING
    # ------------------------------------------------------------------------

    loop L_community_structure:
      purpose: "Refine temporal windowing and community-detection resolution
        until communities are neither too fragmented nor too coarse, and
        cross-time matches (persistence/merge/split/dissolution) are
        plausible given domain knowledge"
      until: "Community partition granularity and cross-time matches are
        judged adequate"
      body:

        transform T_partition_windows :
          intent: define-unit
          manner: "time-partitioning with overlapping windows"
          input: D_papers, S_detection_spec
          output: D_windows
          actor: machine
          description: "Partition 1990-2024 into overlapping time windows
            as specified by S_detection_spec"

        artifact D_windows : entities
          internal structure: episode
          embedment: time
          features:
            - id: f_window_span
              value structure: atomic
              value type: temporal
          description: "Overlapping time windows over the publication period"

        transform T_char_window_graphs :
          intent: characterise
          manner: "define-relations (co-authorship, per window)"
          input: D_authors, D_papers, D_windows
          output: F_coauthor_windows
          actor: machine
          description: "Compute weighted co-authorship subgraph per window"

        artifact F_coauthor_windows : feature(D_windows)
          value structure: relational configuration
          value type: numeric
          representation form: "weighted co-authorship graph per window"

        transform T_anchor_communities :
          intent: define-unit
          manner: "cluster-by-similarity (graph community detection, full period)"
          input: D_authors, F_coauthor_full, S_detection_spec
          output: D_anchor_communities, F_anchor_membership
          actor: machine
          description: "Detect long-term reference communities from the
            full-period network"

        artifact D_anchor_communities : entities
          internal structure: group/cluster
          embedment: set
          features:
            - id: f_size
              value structure: atomic
              value type: numeric
          description: "Long-run reference communities"

        artifact F_anchor_membership : feature(D_authors)
          value structure: atomic
          value type: categorical
          description: "Anchor-community label per author"

        transform T_window_communities :
          intent: define-unit
          manner: "cluster-by-similarity (graph community detection, per window)"
          input: D_authors, F_coauthor_windows, S_detection_spec
          output: D_window_communities, F_window_membership
          actor: machine
          description: "Detect communities independently within each
            windowed snapshot"

        artifact D_window_communities : entities
          internal structure: group/cluster
          embedment: {set, time}
          features:
            - id: f_size
              value structure: atomic
              value type: numeric
            - id: f_window
              value structure: atomic
              value type: reference
          description: "Per-window communities of collaborating authors"

        artifact F_window_membership : feature(D_authors)
          value structure: atomic
          value type: categorical
          description: "Per-window community label per author"

        transform T_char_overlap :
          intent: characterise
          manner: "define-relations (membership overlap across adjacent windows)"
          input: D_window_communities, F_window_membership
          output: F_community_flow
          actor: machine
          description: "Compute weighted overlap of author membership between
            communities in adjacent/overlapping windows"

        artifact F_community_flow : feature(D_window_communities)
          value structure: relational configuration
          value type: numeric
          representation form: "directed weighted graph linking (community,
            window) pairs by membership overlap"

        transform T_project_states :
          intent: contextualise
          manner: "projection-based (community-state embedding)"
          input: D_window_communities, F_community_flow
          output: D_state_space, A_state_projection
          actor: machine
          description: "Embed each (community,window) state in 2D by
            member/topic similarity"

        artifact D_state_space : entities
          internal structure: elementary
          features:
            - id: f_dimensions
              value structure: atomic
              value type: numeric
          description: "Computed 2D projection space for community-window states"

        artifact A_state_projection : arrangement(D_window_communities)
          context: D_state_space
          principle: "similarity-preserving projection of member/topic vectors"
          description: "Layout where proximity indicates persistence across windows"

        transform T_arrange_flow :
          intent: contextualise
          manner: "flow/alluvial arrangement based on temporal order and overlap"
          input: D_window_communities, F_community_flow, D_windows
          output: A_flow_layout
          actor: machine
          description: "Arrange communities along the temporal axis with
            ribbon widths from overlap weights"

        artifact A_flow_layout : arrangement(D_window_communities)
          context: D_windows
          principle: "alluvial/stream layout ordered by time window, ribbon
            width by overlap weight"

        transform T_vis_evolution :
          intent: visualise
          manner: "coordinated alluvial diagram and projection scatterplot"
          input: A_flow_layout, A_state_projection, F_community_flow
          output: V_evolution
          actor: machine
          description: "Render community-flow as alluvial diagram alongside
            a 2D state-projection scatterplot"

        artifact V_evolution : visualisation(A_flow_layout, A_state_projection,
            F_community_flow)
          layout: "alluvial diagram; 2D projection scatterplot"
          form: "stream ribbons; coloured points with trails"
          encoding: "ribbon width/position from F_community_flow; point
            position from A_state_projection; trails connect matched states"

        transform T_abstract_events :
          intent: abstract
          manner: "perception-and-interpretation of evolution events"
          input: V_evolution, F_community_flow
          output: P_evolution_events
          actor: human
          description: "Identify and classify evolution events
            (persist/split/merge/emerge/dissolve) per community trajectory"

        artifact P_evolution_events : pattern(D_window_communities)
          representation form: "labelled event templates per community
            trajectory"

        transform T_assess_structure :
          intent: assess
          manner: "judge community granularity and match plausibility"
          input: V_evolution, P_evolution_events
          output: K_structure_quality
          actor: human
          description: "Judge whether communities are appropriately
            resolved and whether identified matches are plausible"

        artifact K_structure_quality : knowledge(D_window_communities,
            P_evolution_events)
          representation form: "quality judgment"

        if K_structure_quality indicates refinement needed:
          then:
            transform T_refine_detection_spec :
              intent: generate-knowledge
              manner: "formulate methodological adjustment"
              input: K_structure_quality, S_detection_spec, K_provenance_log
              output: S_detection_spec_r, K_provenance_log_r
              actor: human
              description: "Adjust window size/step or clustering resolution;
                append the change to the provenance log"

            artifact S_detection_spec_r : specification
              representation form: "updated parameter settings"

            artifact K_provenance_log_r : knowledge(S_detection_spec_r)
              representation form: "chronological log of specification changes"
              description: "Provenance log updated with this window/resolution change"

            assign:
              S_detection_spec := S_detection_spec_r
              K_provenance_log := K_provenance_log_r
          else:
            exit loop L_community_structure

    end loop L_community_structure

    transform T_knowledge_evolution :
      intent: generate-knowledge
      manner: "formulate-statements"
      input: P_evolution_events, V_evolution
      output: K_evolution
      actor: human
      description: "Formulate conclusions about the number of distinct
        long-run communities and when/how they merged, split, or dissolved"

    artifact K_evolution : knowledge(P_evolution_events, D_window_communities)
      representation form: "statements"

    # ------------------------------------------------------------------------
    # PHASE 4: CORE STABILITY AND LEADERSHIP (with role-classification loop)
    # ------------------------------------------------------------------------

    transform T_char_author_metrics :
      intent: characterise
      manner: "compute-statistics (tenure, centrality, cross-membership)"
      input: D_authors, F_window_membership, F_coauthor_windows
      output: F_author_metrics
      actor: machine
      description: "Compute per-author tenure, within-community centrality
        per window, and cross-community membership count"

    artifact F_author_metrics : feature(D_authors)
      value structure: vector
      value type: numeric

    loop L_role_classification:
      purpose: "Refine role-classification thresholds until core/leader,
        peripheral, and boundary-spanning assignments are judged consistent
        with domain knowledge of the VIS community"
      until: "Classified roles match the analyst's knowledge of known
        research groups and leaders"
      body:

        transform T_classify_authors :
          intent: define-unit
          manner: "rule-based classification (core / peripheral / boundary-spanning)"
          input: D_authors, F_author_metrics, S_role_thresholds
          output: D_author_roles, F_role_label
          actor: hybrid
          description: "Classify authors into roles using current thresholds"

        artifact D_author_roles : entities
          internal structure: group/cluster
          embedment: set
          description: "Groups of authors sharing the same structural role"

        artifact F_role_label : feature(D_authors)
          value structure: atomic
          value type: categorical

        transform T_vis_nodetrix :
          intent: visualise
          manner: "node-link/matrix hybrid (NodeTrix)"
          input: D_window_communities, F_coauthor_windows, F_role_label
          output: V_nodetrix
          actor: machine
          description: "Render a selected community-period's dense
            collaboration core as an adjacency matrix, bridging ties as
            node-link edges"

        artifact V_nodetrix : visualisation(D_window_communities,
            F_coauthor_windows, F_role_label)
          layout: "hybrid node-link and matrix"
          form: "adjacency matrix blocks; node-link edges for external ties"
          encoding: "matrix cell = intra-core edge weight; node colour =
            role label; external edges = bridging ties"

        transform T_vis_author_timeline :
          intent: visualise
          manner: "scarf-plot / event-sequence timeline per author"
          input: D_authors, F_window_membership, D_windows
          output: V_author_timeline
          actor: machine
          description: "Render each author as a track with coloured segments
            indicating community membership per window"

        artifact V_author_timeline : visualisation(D_authors,
            F_window_membership, D_windows)
          layout: "aligned horizontal timelines"
          form: "coloured segments"
          encoding: "row = author; horizontal position = time window;
            colour = community membership"

        transform T_assess_roles :
          intent: assess
          manner: "judge role-classification plausibility"
          input: V_nodetrix, V_author_timeline, F_role_label
          output: K_role_quality
          actor: human
          description: "Judge whether classified core/leader, peripheral,
            and boundary-spanning assignments match known VIS leaders and
            research groups"

        artifact K_role_quality : knowledge(D_author_roles)
          representation form: "quality judgment"

        if K_role_quality indicates refinement needed:
          then:
            transform T_refine_role_thresholds :
              intent: generate-knowledge
              manner: "formulate methodological adjustment"
              input: K_role_quality, S_role_thresholds, K_provenance_log
              output: S_role_thresholds_r, K_provenance_log_r2
              actor: human
              description: "Adjust tenure/centrality thresholds; append the
                change to the provenance log"

            artifact S_role_thresholds_r : specification
              representation form: "updated parameter settings"

            artifact K_provenance_log_r2 : knowledge(S_role_thresholds_r)
              representation form: "chronological log of specification changes"

            assign:
              S_role_thresholds := S_role_thresholds_r
              K_provenance_log := K_provenance_log_r2
          else:
            exit loop L_role_classification

    end loop L_role_classification

    transform T_abstract_stability :
      intent: abstract
      manner: "perception-and-interpretation of stability/leadership patterns"
      input: V_nodetrix, V_author_timeline, F_author_metrics
      output: P_stability_patterns
      actor: human
      description: "Identify stable cores/leaders per community and members
        who move between or span multiple communities"

    artifact P_stability_patterns : pattern(D_authors, D_window_communities)
      representation form: "labelled roles with textual descriptions"

    transform T_knowledge_stability :
      intent: generate-knowledge
      manner: "formulate-statements"
      input: P_stability_patterns
      output: K_stability
      actor: human
      description: "Formulate conclusions about core stability and
        leadership per community"

    artifact K_stability : knowledge(P_stability_patterns)
      representation form: "statements"

    # ------------------------------------------------------------------------
    # PHASE 5: RESEARCH FOCI (HUMAN-STEERED TOPIC MODELLING)
    # ------------------------------------------------------------------------

    transform T_char_text_features :
      intent: characterise
      manner: "encode (term-document representation)"
      input: D_papers
      output: F_text_features
      actor: machine
      description: "Build term-document matrix from titles, abstracts, keywords"

    artifact F_text_features : feature(D_papers)
      value structure: matrix
      value type: numeric
      representation form: "term-document matrix"

    loop L_topic_refinement:
      purpose: "Interactively steer the NMF topic model until topics are
        coherent, non-redundant, and align with recognisable VIS research areas"
      until: "Topics are judged coherent and interpretable"
      body:

        transform T_build_topic_model :
          intent: build-model
          manner: "fit-topic-model (NMF)"
          input: F_text_features, S_topic_spec
          output: M_topic_model
          actor: machine
          description: "Fit NMF topic model using current specification"

        artifact M_topic_model : model(F_text_features)
          model type: "topic model"
          representation form: "matrix factorisation (W,H)"

        transform T_vis_topics :
          intent: visualise
          manner: "topic term/document display"
          input: M_topic_model
          output: V_topics
          actor: machine
          description: "Display top terms per topic and representative documents"

        artifact V_topics : visualisation(M_topic_model)
          layout: "ranked term lists with representative documents"
          form: "ranked term lists, document excerpts"
          encoding: "topic weight -> term rank; document-topic weight ->
            representative document selection"

        transform T_assess_topics :
          intent: assess
          manner: "judge topic coherence and interpretability"
          input: V_topics
          output: K_topic_quality
          actor: human
          description: "Judge whether topics are coherent, distinct, and
            align with known VIS research areas"

        artifact K_topic_quality : knowledge(M_topic_model)
          representation form: "quality judgment"

        if K_topic_quality indicates refinement needed:
          then:
            transform T_refine_topic_spec :
              intent: generate-knowledge
              manner: "formulate methodological adjustment (merge/split/seed topics)"
              input: K_topic_quality, S_topic_spec, K_provenance_log
              output: S_topic_spec_r, K_provenance_log_r3
              actor: human
              description: "Merge/split/seed topics; append the change to
                the provenance log"

            artifact S_topic_spec_r : specification
              representation form: "updated parameter settings and seed constraints"

            artifact K_provenance_log_r3 : knowledge(S_topic_spec_r)
              representation form: "chronological log of specification changes"

            assign:
              S_topic_spec := S_topic_spec_r
              K_provenance_log := K_provenance_log_r3
          else:
            exit loop L_topic_refinement

    end loop L_topic_refinement

    transform T_char_topic_profiles :
      intent: characterise
      manner: "aggregate (topic-mixture per community-period)"
      input: D_window_communities, M_topic_model, D_papers
      output: F_topic_profiles
      actor: machine
      description: "Aggregate topic-mixtures of papers within each
        community-period into a topic profile"

    artifact F_topic_profiles : feature(D_window_communities)
      value structure: vector
      value type: numeric

    transform T_vis_topic_evolution :
      intent: visualise
      manner: "matrix / small-multiples"
      input: F_topic_profiles, D_window_communities, D_windows
      output: V_topic_evolution
      actor: machine
      description: "Visualise topic-profile distributions across communities
        and time"

    artifact V_topic_evolution : visualisation(F_topic_profiles,
        D_window_communities, D_windows)
      layout: "matrix (community x time) / small multiples"
      form: "stacked bars or heatmap cells"
      encoding: "rows = communities; columns = time windows; cell content =
        topic-mixture profile"

    transform T_abstract_foci :
      intent: abstract
      manner: "name-patterns"
      input: V_topic_evolution, F_topic_profiles
      output: P_research_foci
      actor: human
      description: "Assign descriptive labels to dominant topics per
        community-period; identify foci shifts over time"

    artifact P_research_foci : pattern(D_window_communities)
      representation form: "labelled topic descriptions per community-period"

    transform T_knowledge_foci :
      intent: generate-knowledge
      manner: "formulate-statements"
      input: P_research_foci
      output: K_foci
      actor: human
      description: "Formulate conclusions about each community's main
        research foci and their evolution"

    artifact K_foci : knowledge(P_research_foci)
      representation form: "statements"

    # ------------------------------------------------------------------------
    # PHASE 6: CROSS-COMMUNITY MEMBERSHIP OVERLAP (with threshold loop)
    # ------------------------------------------------------------------------

    transform T_char_overlap_matrix :
      intent: characterise
      manner: "define-relations (pairwise membership overlap within a window)"
      input: D_window_communities, F_window_membership
      output: F_overlap_matrix
      actor: machine
      description: "For each window, compute a pairwise overlap matrix among
        communities based on shared authorship"

    artifact F_overlap_matrix : feature(D_window_communities)
      value structure: matrix
      value type: numeric
      representation form: "pairwise community overlap matrix per window"

    loop L_overlap_threshold:
      purpose: "Refine the overlap threshold until the resulting set of
        high-overlap community pairs is judged meaningful rather than
        arbitrary"
      until: "The highlighted set of high-overlap pairs is judged meaningful"
      body:

        transform T_vis_overlap :
          intent: visualise
          manner: "matrix-plot"
          input: F_overlap_matrix, S_overlap_threshold
          output: V_overlap
          actor: machine
          description: "Display community x community overlap matrix per
            window, highlighting pairs above the current threshold"

        artifact V_overlap : visualisation(F_overlap_matrix, S_overlap_threshold)
          layout: "matrix grid, selectable per time window"
          form: "heatmap cells with threshold highlighting"
          encoding: "cell colour intensity = degree of shared authorship;
            highlight = above current threshold"

        transform T_assess_overlap_threshold :
          intent: assess
          manner: "judge meaningfulness of highlighted overlap set"
          input: V_overlap
          output: K_overlap_threshold_quality
          actor: human
          description: "Judge whether the highlighted high-overlap pairs are
            meaningful (e.g., plausible near-merges) or arbitrary"

        artifact K_overlap_threshold_quality : knowledge(F_overlap_matrix)
          representation form: "quality judgment"

        if K_overlap_threshold_quality indicates refinement needed:
          then:
            transform T_refine_overlap_threshold :
              intent: generate-knowledge
              manner: "formulate methodological adjustment"
              input: K_overlap_threshold_quality, S_overlap_threshold, K_provenance_log
              output: S_overlap_threshold_r, K_provenance_log_r4
              actor: human
              description: "Adjust overlap threshold; append the change to
                the provenance log"

            artifact S_overlap_threshold_r : specification
              representation form: "updated parameter settings"

            artifact K_provenance_log_r4 : knowledge(S_overlap_threshold_r)
              representation form: "chronological log of specification changes"

            assign:
              S_overlap_threshold := S_overlap_threshold_r
              K_provenance_log := K_provenance_log_r4
          else:
            exit loop L_overlap_threshold

    end loop L_overlap_threshold

    transform T_abstract_overlap :
      intent: abstract
      manner: "find-salient-groups"
      input: V_overlap
      output: P_overlap_patterns
      actor: human
      description: "Identify community pairs with persistently high overlap,
        candidates for merging or loss of distinctiveness"

    artifact P_overlap_patterns : pattern(D_window_communities)
      representation form: "ranked list of high-overlap community pairs"

    # ------------------------------------------------------------------------
    # INTEGRATED ASSESSMENT (governs whether the outer loop re-enters)
    # ------------------------------------------------------------------------

    transform T_assess_integration :
      intent: assess
      manner: "judge overall coherence of integrated community characterisation"
      input: K_evolution, K_stability, K_foci, P_overlap_patterns
      output: K_integration_quality
      actor: human
      description: "Judge whether the combined picture of communities, cores,
        foci, and overlaps is internally coherent, or whether the underlying
        temporal-windowing/community-detection resolution itself should be
        revisited (e.g., persistent high overlap or indistinguishable foci
        suggesting two 'communities' are really one, or a community is too
        coarse to reveal known sub-groups)"

    artifact K_integration_quality : knowledge(K_evolution, K_stability,
        K_foci, P_overlap_patterns)
      representation form: "quality judgment"

    if K_integration_quality indicates that community/window resolution needs revision:
      then:
        transform T_revise_detection_spec :
          intent: generate-knowledge
          manner: "formulate methodological adjustment based on downstream findings"
          input: K_integration_quality, S_detection_spec, K_provenance_log
          output: S_detection_spec_r2, K_provenance_log_r5
          actor: human
          description: "Revise temporal windowing/community-detection
            resolution based on evidence from role, topic, or overlap
            analysis; append the change to the provenance log; this
            triggers re-execution of the entire inner sequence, beginning
            with L_community_structure"

        artifact S_detection_spec_r2 : specification
          representation form: "updated parameter settings"

        artifact K_provenance_log_r5 : knowledge(S_detection_spec_r2)
          representation form: "chronological log of specification changes"

        assign:
          S_detection_spec := S_detection_spec_r2
          K_provenance_log := K_provenance_log_r5
      else:
        exit loop L_integrated_analysis

end loop L_integrated_analysis

# ============================================================================
# FINAL SYNTHESIS
# ============================================================================

transform T_final_synthesis :
  intent: generate-knowledge
  manner: "formulate-statements (integrated synthesis)"
  input: K_evolution, K_stability, K_foci, P_overlap_patterns
  output: K_findings
  actor: human
  description: "Synthesise conclusions across community evolution, core
    stability/leadership, research foci, and cross-community overlap"

artifact K_findings : knowledge(D_window_communities, D_authors)
  representation form: "statements and structured summary"
  description: "Integrated findings: number/identity of major communities,
    core stability and leadership, research foci and their evolution,
    membership overlap and its change over time, and merge/split/
    dissolution events with plausible interpretations"