workflow vis-community-evolution
  template: characterise -> visualise -> assess -> define-unit ->
            characterise -> define-unit ->
            loop(build-model -> define-unit -> characterise ->
                 contextualise -> visualise -> abstract -> assess) ->
            characterise ->
            loop(build-model -> define-unit -> characterise ->
                 visualise -> abstract -> assess) ->
            define-unit -> characterise -> contextualise -> visualise ->
            abstract -> generate-knowledge ->
            loop(build-model -> define-unit -> characterise ->
                 visualise -> assess) ->
            generate-knowledge
  description: "Identify overlapping, evolving co-authorship communities
    in IEEE VIS publications; characterise their stable cores, leaders,
    research foci, membership overlap, and community lineage events."

# ============================================================================
# INPUT DATA, DOMAIN KNOWLEDGE, AND INITIAL SETTINGS
# ============================================================================

artifact D_papers_raw : entities
  origin: given
  internal structure: elementary
  embedment: {set, time}
  features:
    - id: paper_id
      value structure: atomic
      value type: reference
      description: "Unique paper identifier"
    - id: publication_year
      value structure: atomic
      value type: temporal
      description: "Publication year from 1990 to 2024"
    - id: venue
      value structure: atomic
      value type: categorical
      description: "VIS, InfoVis, VAST, or SciVis venue"
    - id: authors
      value structure: list
      value type: reference
      description: "DBLP-disambiguated author identifiers and raw names"
    - id: bibliographic_text
      value structure: vector
      value type: text
      description: "Title, abstract, and author keywords"
    - id: citations
      value structure: relational configuration
      value type: reference
      description: "Citation links where available, otherwise citation counts"
  description: "IEEE VIS conference paper records with authorship,
    bibliographic text, venue, year, and citation information"

artifact K_domain_knowledge : knowledge(D_papers_raw)
  origin: given
  representation form: "annotations and interpretive criteria"
  description: "Visualization-domain knowledge used to judge meaningful
    communities, distinguish venue-history effects from intellectual
    change, interpret topics, and review lineage events"

artifact S_temporal_views : specification
  origin: given
  representation form: "configuration schema"
  description: "Annual, rolling three- or five-year, and broader-era
    temporal views; specifies the candidate temporal windows to retain"

artifact S_community_analysis : specification
  origin: given
  representation form: "configuration schema"
  description: "Initial community-analysis choices: fractional weighting
    of co-authorship ties, overlapping community method, candidate
    resolutions, weak-tie treatment, and selection criteria"

artifact S_topic_analysis : specification
  origin: given
  representation form: "configuration schema"
  description: "Initial topic-analysis choices: text preprocessing,
    generic-term removal, topic-model family, number of topics, and
    topic-editing constraints"

artifact S_lineage_matching : specification
  origin: given
  representation form: "rules and thresholds"
  description: "Rules for matching communities across periods using
    weighted author membership, stable-core overlap, topical similarity,
    and collaboration-structure similarity"

artifact S_robustness_analysis : specification
  origin: given
  representation form: "parameter settings"
  description: "Alternative window widths, edge weights, weak-tie filters,
    community resolutions, and topic-model settings for sensitivity checks"

# ============================================================================
# DATA AUDIT AND PREPARATION
# ============================================================================

transform T_audit_records :
  intent: characterise
  manner: "compute data-completeness and coverage statistics"
  input: D_papers_raw
  output: F_record_quality
  actor: machine
  description: "Identify duplicate papers, missing author or text fields,
    unusually large author teams, yearly venue coverage, and the available
    form of citation information"

artifact F_record_quality : feature(D_papers_raw)
  value structure: vector
  value type: {numeric, categorical}
  description: "Completeness, duplication, author-team-size, venue-coverage,
    and citation-availability indicators for paper records"

transform T_visualise_audit :
  intent: visualise
  manner: "temporal coverage and quality overview"
  input: D_papers_raw, F_record_quality
  output: V_data_audit
  actor: machine
  description: "Show yearly paper counts by venue and linked views of
    missingness, duplicates, author-team sizes, and citation coverage"

artifact V_data_audit : visualisation(D_papers_raw, F_record_quality)
  layout: "aligned yearly timelines and linked quality summaries"
  form: "stacked bars, distributions, and tabular record inspector"
  encoding: "time and venue determine publication-count displays; colour
    and highlighting indicate data-quality conditions"
  description: "Visual audit interface for checking data coverage and
    identifying records requiring treatment"

transform T_assess_audit :
  intent: assess
  manner: "judge data adequacy and required cleaning"
  input: V_data_audit, F_record_quality, K_domain_knowledge
  output: K_audit_assessment
  actor: human
  description: "Determine how duplicate records, missing information,
    unusual team sizes, and venue-coverage changes should be handled"

artifact K_audit_assessment : knowledge(D_papers_raw, F_record_quality)
  representation form: "quality judgment and cleaning decisions"
  description: "Analyst assessment of data quality and justified treatment
    decisions for the bibliographic corpus"

transform T_prepare_records :
  intent: define-unit
  manner: "filter, deduplicate, and normalise paper records"
  input: D_papers_raw, K_audit_assessment
  output: D_papers
  actor: hybrid
  description: "Create an analysis-ready paper corpus; retain DBLP author
    identifiers, preserve display names, normalise bibliographic text, and
    apply agreed data-treatment decisions"

artifact D_papers : entities
  internal structure: elementary
  embedment: {set, time}
  features:
    - id: publication_year
      value structure: atomic
      value type: temporal
      description: "Validated publication year"
    - id: venue
      value structure: atomic
      value type: categorical
      description: "Publication venue"
    - id: author_ids
      value structure: list
      value type: reference
      description: "Validated DBLP author identifiers"
    - id: clean_text
      value structure: vector
      value type: text
      description: "Normalised title, abstract, and keywords"
  description: "Prepared IEEE VIS paper corpus for collaboration and topic analysis"

# ============================================================================
# AUTHOR, TEXT, AND TEMPORAL NETWORK REPRESENTATIONS
# ============================================================================

transform T_define_authors :
  intent: define-unit
  manner: "group-by-entity"
  input: D_papers
  output: D_authors, F_authorship
  actor: machine
  description: "Define unique researchers from DBLP identifiers and retain
    paper-to-author affiliations"

artifact D_authors : entities
  internal structure: group/cluster
  embedment: set
  features:
    - id: author_id
      value structure: atomic
      value type: reference
      description: "Unique DBLP author identifier"
    - id: display_names
      value structure: list
      value type: text
      description: "Raw author-name strings retained for inspection"
  description: "Researchers represented through their associated VIS papers"

artifact F_authorship : feature(D_papers)
  value structure: relational configuration
  value type: reference
  representation form: "paper-author bipartite network"
  description: "Paper-to-author relationships preserving complete author teams"

transform T_characterise_relations :
  intent: characterise
  manner: "define-relations (fractionally weighted co-authorship)"
  input: D_papers, D_authors, F_authorship
  output: F_coauthorship, F_text_representation
  actor: machine
  description: "Compute weighted co-authorship relations while preventing
    large author teams from dominating, and encode paper text for topic analysis"

artifact F_coauthorship : feature(D_authors)
  value structure: relational configuration
  value type: numeric
  representation form: "weighted temporal co-authorship network"
  description: "Author collaboration ties with fractional paper contributions
    and time references"

artifact F_text_representation : feature(D_papers)
  value structure: matrix
  value type: numeric
  representation form: "document-term representation"
  description: "Machine-processable representation of normalised titles,
    abstracts, and keywords"

transform T_define_snapshots :
  intent: define-unit
  manner: "time-partitioning and network aggregation"
  input: D_papers, D_authors, F_coauthorship, S_temporal_views
  output: D_network_snapshots
  actor: machine
  description: "Construct annual, rolling-window, and broad-era weighted
    co-authorship network snapshots"

artifact D_network_snapshots : entities
  internal structure: formation
  embedment: time
  features:
    - id: window_extent
      value structure: atomic
      value type: temporal
      description: "Time interval represented by the snapshot"
    - id: edge_weight
      value structure: relational configuration
      value type: numeric
      description: "Fractionally weighted co-authorship network"
  description: "Time-indexed co-authorship network snapshots at multiple scales"

assign:
  S_community_current := S_community_analysis

# ============================================================================
# OVERLAPPING COMMUNITY DISCOVERY AND REFINEMENT
# ============================================================================

loop L_community_refinement:
  purpose: "Find an interpretable and stable overlapping community structure
    while allowing resolution, weighting, and temporal choices to be revised"
  until: "The selected communities are sufficiently cohesive, stable across
    adjacent periods, topically interpretable, and credible to the analyst"
  body:

    transform T_fit_community_model :
      intent: build-model
      manner: "fit overlapping community-detection model"
      input: D_network_snapshots, F_coauthorship, S_community_current
      output: M_community_model
      actor: machine
      description: "Fit a candidate overlapping community model in each
        temporal network snapshot at the current resolution and settings"

    artifact M_community_model : model(D_network_snapshots, F_coauthorship)
      model type: "overlapping community-detection model"
      representation form: "membership-weight and network-partition parameters"
      description: "Computational representation of candidate overlapping
        author communities across temporal snapshots"

    transform T_define_communities :
      intent: define-unit
      manner: "derive overlapping community groups from membership weights"
      input: D_network_snapshots, D_authors, M_community_model
      output: D_communities, F_community_membership
      actor: machine
      description: "Define community instances for each time window and
        assign authors weighted memberships in one or more communities"

    artifact D_communities : entities
      internal structure: group/cluster
      embedment: time
      features:
        - id: active_window
          value structure: atomic
          value type: temporal
          description: "Time window in which the community instance is active"
      description: "Overlapping author communities observed in temporal snapshots"

    artifact F_community_membership : feature(D_authors)
      value structure: matrix
      value type: numeric
      representation form: "author × community-time membership weights"
      description: "Degree of each author's membership in each community
        over time"

    transform T_characterise_communities :
      intent: characterise
      manner: "compute core-periphery, leadership, and structural metrics"
      input: D_communities, D_authors, F_community_membership,
             F_coauthorship
      output: F_author_roles, F_community_metrics
      actor: machine
      description: "Identify candidate stable-core members, leaders,
        peripheral contributors, and boundary spanners using persistence,
        within-community collaboration, brokerage, productivity, and impact"

    artifact F_author_roles : feature(D_authors)
      value structure: vector
      value type: {categorical, numeric, temporal}
      description: "Time-resolved stable-core, leader, peripheral, and
        boundary-spanner roles with supporting scores"

    artifact F_community_metrics : feature(D_communities)
      value structure: vector
      value type: {numeric, temporal}
      description: "Community size, density, core persistence, overlap,
        repeated collaboration, publication volume, and impact indicators"

    transform T_contextualise_community_states :
      intent: contextualise
      manner: "projection-based dynamic network-state map"
      input: D_network_snapshots, F_community_metrics
      output: D_state_space, A_snapshot_states
      actor: machine
      description: "Project temporal network snapshots into a state space
        where proximity reflects similarity of community-network structure"

    artifact D_state_space : entities
      internal structure: elementary
      features:
        - id: dimensions
          value structure: atomic
          value type: numeric
          description: "Two dimensions of the computed state space"
      description: "Computed projection context for comparing network states"

    artifact A_snapshot_states : arrangement(D_network_snapshots)
      context: D_state_space
      principle: "similarity-preserving projection of network-state features"
      description: "Arrangement of temporal network snapshots by structural similarity"

    transform T_visualise_communities :
      intent: visualise
      manner: "coordinated community-structure views"
      input: D_communities, D_authors, F_community_membership,
             F_author_roles, F_community_metrics, A_snapshot_states
      output: V_community_structure
      actor: machine
      description: "Provide linked community views: temporal state map,
        community-size summaries, core-periphery profiles, membership
        histories, and NodeTrix-style matrix-plus-node-link inspection"

    artifact V_community_structure : visualisation(D_communities, D_authors,
        F_community_membership, F_author_roles, F_community_metrics,
        A_snapshot_states)
      layout: "coordinated state projection, temporal summaries, membership
        matrix, and selected-community matrix-plus-node-link view"
      form: "projected points, timelines, ribbons, matrices, and node-link diagrams"
      encoding: "community and author colour encode membership; matrix cells
        and links encode collaboration strength; size encodes membership or
        publication volume; time encodes snapshot order"
      description: "Interactive visual interface for inspecting candidate
        communities, core members, leaders, and cross-community ties"

    transform T_interpret_community_patterns :
      intent: abstract
      manner: "perception-and-interpretation of candidate communities"
      input: V_community_structure, F_author_roles, F_community_metrics,
             K_domain_knowledge
      output: P_candidate_community_structure
      actor: human
      description: "Interpret salient stable communities, possible
        subcommunities, unusual overlaps, and plausible leader/core roles"

    artifact P_candidate_community_structure : pattern(D_communities)
      representation form: "annotated community and role descriptions"
      description: "Analyst interpretations of cohesive communities,
        cores, leaders, boundary spanners, and suspicious fragmentations"

    transform T_assess_communities :
      intent: assess
      manner: "evaluate community quality, stability, and interpretability"
      input: D_communities, F_community_membership, F_community_metrics,
             V_community_structure, P_candidate_community_structure,
             S_community_current, K_domain_knowledge
      output: K_community_assessment, S_community_revised
      actor: hybrid
      description: "Evaluate cohesion, separation, parameter stability,
        persistence, and topical plausibility; determine whether community
        settings require further refinement"

    artifact K_community_assessment : knowledge(D_communities,
        F_community_metrics)
      representation form: "quality judgment"
      description: "Assessment of whether the community solution is
        fragmented, overly merged, unstable, or sufficiently interpretable"

    artifact S_community_revised : specification
      representation form: "revised configuration schema"
      description: "Updated community resolution, temporal-view selection,
        tie weighting, filtering, or model choice for another iteration"

    if K_community_assessment indicates further refinement needed:
      then:
        assign:
          S_community_current := S_community_revised
      else:
        exit loop L_community_refinement

end loop L_community_refinement

# ============================================================================
# TOPIC CHARACTERISATION AND HUMAN-STEERED TOPIC REFINEMENT
# ============================================================================

transform T_characterise_community_corpora :
  intent: characterise
  manner: "aggregate weighted document corpora"
  input: D_papers, D_communities, F_community_membership,
         F_text_representation
  output: F_community_corpora
  actor: machine
  description: "Construct weighted community-time document corpora.
    Contributions from authors belonging to several communities are
    fractionally allocated while preserving links to full papers."

artifact F_community_corpora : feature(D_communities)
  value structure: matrix
  value type: numeric
  representation form: "weighted community-time document-term matrix"
  description: "Textual evidence associated with each community instance"

assign:
  S_topic_current := S_topic_analysis

loop L_topic_refinement:
  purpose: "Develop interpretable topic profiles for communities and
    refine topic representations with analyst guidance"
  until: "Topics are distinct, meaningful to visualization researchers,
    and adequately explain communities' research foci and change over time"
  body:

    transform T_fit_topic_model :
      intent: build-model
      manner: "fit interpretable topic model"
      input: F_community_corpora, F_text_representation, S_topic_current
      output: M_topic_model
      actor: machine
      description: "Fit an initial topic model to weighted paper text from
        community-time corpora"

    artifact M_topic_model : model(F_community_corpora, F_text_representation)
      model type: "topic model"
      representation form: "nonnegative matrix factorisation or comparable
        topic-term and topic-document matrices"
      description: "Model of research topics and their prevalence in
        community-time paper corpora"

    transform T_define_topics :
      intent: define-unit
      manner: "derive topic groups and community topic mixtures"
      input: M_topic_model, F_community_corpora
      output: D_topics, F_topic_mixture, F_topic_terms
      actor: machine
      description: "Define candidate topics, representative papers, terms,
        and the mixture of topics associated with each community over time"

    artifact D_topics : entities
      internal structure: group/cluster
      embedment: set
      description: "Candidate research topics represented by associated
        terms and papers"

    artifact F_topic_mixture : feature(D_communities)
      value structure: vector
      value type: numeric
      description: "Topic prevalence profile for each community-time instance"

    artifact F_topic_terms : feature(D_topics)
      value structure: list
      value type: text
      description: "Ranked representative terms and papers for each topic"

    transform T_characterise_topic_change :
      intent: characterise
      manner: "compute topic evolution and cross-community similarity"
      input: D_topics, F_topic_mixture, F_topic_terms
      output: F_topic_trends, F_topic_similarity
      actor: machine
      description: "Calculate persistent, emerging, declining, and shared
        topics, plus topic diversity and topical similarity between communities"

    artifact F_topic_trends : feature(D_communities)
      value structure: vector
      value type: {numeric, temporal}
      description: "Temporal topic prevalence, diversity, emergence, and decline"

    artifact F_topic_similarity : feature(D_communities)
      value structure: matrix
      value type: numeric
      representation form: "pairwise community topical-similarity matrix"
      description: "Similarity of communities' topic profiles"

    transform T_visualise_topics :
      intent: visualise
      manner: "topic timeline and document inspection"
      input: D_communities, D_topics, F_topic_mixture, F_topic_terms,
             F_topic_trends
      output: V_topics
      actor: machine
      description: "Show topic timelines, community-topic heatmaps, topic
        terms, representative papers, and paper-level textual evidence"

    artifact V_topics : visualisation(D_communities, D_topics,
        F_topic_mixture, F_topic_terms, F_topic_trends)
      layout: "aligned community timelines, topic heatmap, and linked paper inspector"
      form: "stacked area charts, heatmaps, ranked term lists, and document cards"
      encoding: "time determines horizontal position; colour identifies
        topics; area or intensity encodes topic prevalence"
      description: "Interactive interface for interpreting community research foci"

    transform T_interpret_topics :
      intent: abstract
      manner: "name and refine research-focus patterns"
      input: V_topics, D_topics, F_topic_terms, K_domain_knowledge
      output: P_research_foci
      actor: human
      description: "Name meaningful topics, identify redundant or mixed
        topics, and relate topic patterns to known visualization research areas"

    artifact P_research_foci : pattern(D_topics, D_communities)
      representation form: "named topic descriptions and temporal focus patterns"
      description: "Interpreted research foci characterising communities
        and their evolution"

    transform T_assess_topics :
      intent: assess
      manner: "evaluate topic coherence and analytical usefulness"
      input: M_topic_model, V_topics, P_research_foci, S_topic_current
      output: K_topic_assessment, S_topic_revised
      actor: human
      description: "Judge topic coherence, distinctness, coverage, and
        explanatory value; decide whether terms, seeds, topic number, or
        topic structure should be revised"

    artifact K_topic_assessment : knowledge(D_topics, M_topic_model)
      representation form: "quality judgment"
      description: "Assessment of topic-model adequacy and need for refinement"

    artifact S_topic_revised : specification
      representation form: "revised topic-model settings and constraints"
      description: "Analyst revisions such as topic merging or splitting,
        generic-term removal, seeded concepts, preprocessing changes, or
        revised topic count"

    if K_topic_assessment indicates topic refinement needed:
      then:
        assign:
          S_topic_current := S_topic_revised
      else:
        exit loop L_topic_refinement

end loop L_topic_refinement

# ============================================================================
# COMMUNITY LINEAGES, OVERLAP, AND EVOLUTION EVENTS
# ============================================================================

transform T_define_lineages :
  intent: define-unit
  manner: "match communities across adjacent temporal windows"
  input: D_communities, F_community_membership, F_author_roles,
         F_topic_mixture, F_topic_similarity, S_lineage_matching
  output: D_community_lineages, F_lineage_membership, F_event_candidates
  actor: hybrid
  description: "Match community instances through time, weighting
    stable-core overlap more strongly than peripheral overlap, and derive
    candidate continuation, growth, merge, split, birth, dissolution,
    temporary-disappearance, and reorientation events"

artifact D_community_lineages : entities
  internal structure: sequence
  embedment: set
  features:
    - id: lifespan
      value structure: atomic
      value type: temporal
      description: "Temporal span of the community lineage"
  description: "Community lineages linking related community instances over time"

artifact F_lineage_membership : feature(D_communities)
  value structure: relational configuration
  value type: reference
  representation form: "predecessor-successor lineage graph"
  description: "Links between community instances and their inferred lineages"

artifact F_event_candidates : feature(D_community_lineages)
  value structure: list
  value type: categorical
  description: "Candidate evolution events with affected predecessor and
    successor communities"

transform T_characterise_overlap_and_evidence :
  intent: characterise
  manner: "compute overlap, mobility, and supporting evidence"
  input: D_authors, D_communities, D_community_lineages,
         F_community_membership, F_author_roles, F_topic_mixture,
         F_event_candidates, D_papers
  output: F_overlap, F_member_transitions, F_event_evidence
  actor: machine
  description: "Compute pairwise membership overlap, shared authors,
    multi-community participation, author transitions, shared papers,
    topical changes, venue shifts, and available citation evidence"

artifact F_overlap : feature(D_communities)
  value structure: matrix
  value type: numeric
  representation form: "time-resolved pairwise community-overlap matrix"
  description: "Strength and temporal change of shared membership between communities"

artifact F_member_transitions : feature(D_authors)
  value structure: relational configuration
  value type: reference
  representation form: "author-to-community transition histories"
  description: "Researchers' memberships, mobility, and simultaneous
    participation in several communities"

artifact F_event_evidence : feature(D_community_lineages)
  value structure: vector
  value type: {numeric, categorical, temporal, text}
  description: "Structural, membership, topical, paper, venue, and
    citation evidence supporting each candidate event"

artifact D_lineage_timeline : entities
  origin: given
  internal structure: elementary
  embedment: time
  features:
    - id: date
      value structure: atomic
      value type: temporal
      description: "Time position for lineage visualisation"
  description: "Temporal reference context for community-lineage displays"

transform T_contextualise_lineages :
  intent: contextualise
  manner: "time-based lineage arrangement"
  input: D_communities, D_lineage_timeline, F_lineage_membership
  output: A_lineage_timeline
  actor: machine
  description: "Arrange community instances by time and lineage relationship
    for visual tracing of continuations, merges, and splits"

artifact A_lineage_timeline : arrangement(D_communities)
  context: D_lineage_timeline
  principle: "temporal position with lineage-preserving band placement"
  description: "Time-based arrangement of community instances within lineages"

transform T_visualise_evolution :
  intent: visualise
  manner: "coordinated lineage, overlap, and event-investigation views"
  input: A_lineage_timeline, D_community_lineages, F_event_candidates,
         F_event_evidence, F_overlap, F_member_transitions, F_author_roles,
         F_topic_trends
  output: V_community_evolution
  actor: machine
  description: "Show a lineage diagram, membership ribbons, overlap matrix,
    selected-community NodeTrix view, topic timelines, and evidence-linked
    paper inspector"

artifact V_community_evolution : visualisation(A_lineage_timeline,
        D_community_lineages, F_event_candidates, F_event_evidence,
        F_overlap, F_member_transitions, F_author_roles, F_topic_trends)
  layout: "community lineage bands with coordinated membership, overlap,
    topic, matrix-network, and paper-detail views"
  form: "alluvial bands, ribbons, heatmaps, matrices, node-link diagrams,
    timelines, and document cards"
  encoding: "band width encodes active membership or publication volume;
    links encode lineage relations; colours encode community/topic identity;
    highlighting exposes shared authors, event evidence, and selected papers"
  description: "Interactive visual workspace for examining community
    persistence, overlap, mobility, and evolutionary events"

transform T_review_evolution_events :
  intent: abstract
  manner: "perception-and-interpretation of lineage events"
  input: V_community_evolution, F_event_candidates, F_event_evidence,
         P_research_foci, K_domain_knowledge
  output: P_reviewed_evolution_events
  actor: human
  description: "Review candidate events against underlying members,
    collaboration structure, representative papers, research foci, venues,
    and citations; distinguish genuine events from sparse-data artifacts"

artifact P_reviewed_evolution_events : pattern(D_community_lineages)
  representation form: "reviewed event annotations"
  description: "Analyst-reviewed continuations, merges, splits, births,
    dissolutions, temporary disappearances, and topical reorientations"

transform T_formulate_event_explanations :
  intent: generate-knowledge
  manner: "formulate evidence-backed explanations"
  input: P_reviewed_evolution_events, P_research_foci, F_event_evidence,
         K_domain_knowledge
  output: K_evolution_explanations
  actor: human
  description: "Formulate cautious explanations of when and why community
    changes occurred, explicitly distinguishing evidence-backed hypotheses
    from causal claims"

artifact K_evolution_explanations : knowledge(P_reviewed_evolution_events,
    P_research_foci, F_event_evidence)
  representation form: "annotated explanatory statements"
  description: "Evidence-backed interpretations of community evolution,
    including likely structural and topical reasons for major events"

# ============================================================================
# ROBUSTNESS AND UNCERTAINTY ANALYSIS
# ============================================================================

assign:
  S_robustness_current := S_robustness_analysis

loop L_robustness_analysis:
  purpose: "Test whether community, lineage, and topical conclusions persist
    under reasonable alternative analytical choices"
  until: "The analyst has examined sufficient plausible alternatives and
    can distinguish robust findings from parameter-sensitive findings"
  body:

    transform T_fit_alternative_models :
      intent: build-model
      manner: "fit alternative community and topic models"
      input: D_network_snapshots, F_coauthorship, F_community_corpora,
             S_robustness_current
      output: M_alternative_community_model, M_alternative_topic_model
      actor: machine
      description: "Re-run community and topic modelling under selected
        alternative temporal windows, edge weights, filters, resolutions,
        preprocessing choices, and topic-model settings"

    artifact M_alternative_community_model : model(D_network_snapshots,
        F_coauthorship)
      model type: "alternative overlapping community-detection model"
      description: "One sensitivity-analysis community model configuration"

    artifact M_alternative_topic_model : model(F_community_corpora)
      model type: "alternative topic model"
      description: "One sensitivity-analysis topic model configuration"

    transform T_define_alternative_results :
      intent: define-unit
      manner: "derive alternative communities, topics, and lineages"
      input: D_network_snapshots, D_authors, M_alternative_community_model,
             M_alternative_topic_model, S_lineage_matching
      output: D_alternative_communities, D_alternative_lineages,
              F_alternative_membership, F_alternative_topic_mixture
      actor: machine
      description: "Derive comparable alternative community memberships,
        topic profiles, and lineage structures for sensitivity comparison"

    artifact D_alternative_communities : entities
      internal structure: group/cluster
      embedment: time
      description: "Community instances obtained under an alternative configuration"

    artifact D_alternative_lineages : entities
      internal structure: sequence
      embedment: set
      description: "Lineages obtained under an alternative configuration"

    artifact F_alternative_membership : feature(D_authors)
      value structure: matrix
      value type: numeric
      description: "Alternative author-community membership weights"

    artifact F_alternative_topic_mixture : feature(D_alternative_communities)
      value structure: vector
      value type: numeric
      description: "Alternative community topic-prevalence profiles"

    transform T_characterise_robustness :
      intent: characterise
      manner: "compare alternative analytical results"
      input: D_communities, D_community_lineages, F_community_membership,
             F_topic_mixture, D_alternative_communities,
             D_alternative_lineages, F_alternative_membership,
             F_alternative_topic_mixture
      output: F_result_robustness
      actor: machine
      description: "Measure agreement and sensitivity of community cores,
        memberships, leaders, lineages, events, and research foci across
        alternative analysis configurations"

    artifact F_result_robustness : feature(D_community_lineages)
      value structure: vector
      value type: {numeric, categorical}
      description: "Stability scores and robust/tentative/uncertain labels
        for communities, topics, and lineage events"

    transform T_visualise_robustness :
      intent: visualise
      manner: "comparative sensitivity display"
      input: F_result_robustness, D_communities, D_alternative_communities,
             D_community_lineages, D_alternative_lineages
      output: V_robustness
      actor: machine
      description: "Compare primary and alternative solutions, highlighting
        stable communities and events as well as parameter-sensitive results"

    artifact V_robustness : visualisation(F_result_robustness, D_communities,
        D_alternative_communities, D_community_lineages,
        D_alternative_lineages)
      layout: "aligned solution comparison and stability summaries"
      form: "matched community bands, agreement matrices, and ranked stability plots"
      encoding: "alignment links comparable results; colour and opacity
        encode robustness category and stability score"
      description: "Visual evidence for judging robustness and uncertainty"

    transform T_assess_robustness :
      intent: assess
      manner: "judge sensitivity-analysis sufficiency"
      input: V_robustness, F_result_robustness, S_robustness_current,
             K_domain_knowledge
      output: K_robustness_assessment, S_robustness_revised
      actor: human
      description: "Decide whether the tested alternatives sufficiently
        cover plausible analytical choices or whether additional settings
        require examination"

    artifact K_robustness_assessment : knowledge(F_result_robustness)
      representation form: "quality judgment"
      description: "Assessment of which findings are robust, tentative,
        uncertain, and whether further sensitivity analysis is needed"

    artifact S_robustness_revised : specification
      representation form: "revised parameter settings"
      description: "Additional alternative settings selected for robustness testing"

    if K_robustness_assessment indicates additional alternatives needed:
      then:
        assign:
          S_robustness_current := S_robustness_revised
      else:
        exit loop L_robustness_analysis

end loop L_robustness_analysis

# ============================================================================
# SYNTHESIS AND REPORTING
# ============================================================================

transform T_synthesise_findings :
  intent: generate-knowledge
  manner: "formulate analytical report"
  input: D_community_lineages, F_author_roles, F_community_metrics,
         P_research_foci, P_reviewed_evolution_events,
         K_evolution_explanations, K_robustness_assessment,
         F_result_robustness
  output: K_community_findings
  actor: human
  description: "Produce a documented account of the number of active
    communities and long-term lineages, their cores and leaders, research
    foci, overlap and mobility, evolutionary events, supporting evidence,
    and uncertainty"

artifact K_community_findings : knowledge(D_community_lineages,
    P_research_foci, P_reviewed_evolution_events, F_result_robustness)
  representation form: "annotated analytical report and provenance record"
  description: "Final evidence-linked findings about the intellectual
    structure and evolution of the IEEE VIS research community"