workflow vastopolis-outbreak-origin-and-transmission
  template: characterise (extract-symptom-features) ->
            loop(assess -> characterise (refine-lexicon)) ->
            define-unit (filter-illness-events) ->
            define-unit (daily-episodes) -> characterise (daily-profile) ->
            define-unit (cluster-days) -> contextualise (calendar) ->
            visualise -> abstract -> generate-knowledge ->
            define-unit (derive-places) -> characterise (place-timeseries) ->
            characterise (per-capita-incidence) -> contextualise (map) ->
            visualise -> abstract ->
            characterise (zone-incidence) -> define-unit (cluster-zones) ->
            contextualise (map) -> visualise -> build-model (growth) ->
            characterise (residuals) -> visualise -> abstract ->
            characterise (downwind-alignment) ->
            loop(define-unit (lag-windows) -> characterise (cross-impact) ->
                 visualise -> assess) ->
            generate-knowledge ->
            characterise (social-mentions) -> define-unit (social-network) ->
            visualise -> abstract ->
            visualise (water-overlay) -> abstract ->
            generate-knowledge (mechanism-checklist) ->
            generate-knowledge (final-report)
  description: "Visual analytics workflow for identifying the spatio-temporal
    origin of a flu-like outbreak in Vastopolis from geolocated microblogs,
    and for adjudicating among candidate transmission mechanisms (airborne,
    person-to-person, waterborne) using map, population, and wind data."

# ============================================================================
# INPUT ARTIFACTS
# ============================================================================

artifact D_microblogs : entities
  origin: given
  internal structure: elementary
  embedment: {space, time}
  features:
    - id: text_content
      value structure: atomic
      value type: text
      description: "Raw message text"
  description: "Geolocated microblog messages posted from mobile devices
    over several days, each with timestamp, GPS coordinates, and text
    content"

artifact D_map_features : entities
  origin: given
  internal structure: elementary
  embedment: space
  features:
    - id: feature_type
      value structure: atomic
      value type: categorical
      description: "Category of map feature: highway, hospital, landmark,
        water body"
  description: "Static geographic features of the Vastopolis metropolitan
    area, used as map context"

artifact D_zones : entities
  origin: given
  internal structure: region
  embedment: space
  features:
    - id: population
      value structure: atomic
      value type: numeric
      description: "Resident population of the zone"
  description: "13 city zones of Vastopolis with population statistics"

artifact D_weather : entities
  origin: given
  internal structure: elementary
  embedment: time
  features:
    - id: wind_speed
      value structure: atomic
      value type: numeric
      description: "Daily wind speed"
    - id: wind_direction
      value structure: atomic
      value type: {numeric, spatial}
      description: "Daily wind direction (bearing)"
  description: "Daily weather observations including wind speed and
    direction"

artifact D_calendar : entities
  origin: given
  internal structure: elementary
  embedment: time
  features:
    - id: date
      value structure: atomic
      value type: temporal
      description: "Calendar date"
  description: "Calendar days spanning the observation period, used as
    arrangement context"

artifact S_symptom_lexicon : specification
  origin: given
  representation form: "keyword lexicon"
  description: "Flu-related symptom terms and severity indicators (fever,
    cough, vomiting, hospital, death, etc.) used to seed text extraction"

# ============================================================================
# STAGE A: EXTRACT AND VALIDATE ILLNESS-REPORT EVENTS FROM TEXT
# ============================================================================

transform T_extract_symptoms :
  intent: characterise
  manner: "extract (keyword/entity extraction of symptom and severity
    terms)"
  input: D_microblogs, S_symptom_lexicon
  output: F_symptom_features
  actor: machine
  description: "Extract symptom mentions, severity indicators
    (hospitalization, death), and embedded place references from message
    text"

artifact F_symptom_features : feature(D_microblogs)
  value structure: vector
  value type: {categorical, ordinal, text}
  description: "Per-message symptom type(s), severity level, and any
    embedded place mentions"

loop L_extraction_validation:
  purpose: "Validate and correct automatically extracted symptom/severity
    indicators against raw message text before trusting the derived event
    set"
  until: "Sampled false positive/negative rate in extracted indicators is
    acceptable to the analyst"
  body:

    transform T_assess_extraction :
      intent: assess
      manner: "sample and inspect raw text against extracted indicators"
      input: F_symptom_features, D_microblogs
      output: K_extraction_quality
      actor: human
      description: "Sample messages and check extracted symptom/severity
        labels against raw text for false positives (e.g., sarcastic
        'sick of...') and false negatives"

    artifact K_extraction_quality : knowledge(F_symptom_features)
      representation form: "quality judgment"
      description: "Judgment of whether extraction lexicon/rules yield an
        acceptable false positive/negative rate"

    if K_extraction_quality indicates refinement needed:
      then:
        transform T_refine_lexicon :
          intent: characterise
          manner: "refine extraction lexicon/rules"
          input: D_microblogs, S_symptom_lexicon, K_extraction_quality
          output: F_symptom_features_r, S_symptom_lexicon_r
          actor: human
          description: "Adjust keyword lexicon or extraction rules based on
            observed errors and re-extract"

        artifact F_symptom_features_r : feature(D_microblogs)
          value structure: vector
          value type: {categorical, ordinal, text}
          description: "Updated per-message symptom/severity/place-mention
            indicators"

        artifact S_symptom_lexicon_r : specification
          representation form: "keyword lexicon"
          description: "Revised symptom lexicon"

        assign:
          F_symptom_features := F_symptom_features_r
          S_symptom_lexicon := S_symptom_lexicon_r
      else:
        exit loop L_extraction_validation

end loop L_extraction_validation

transform T_define_illness_events :
  intent: define-unit
  manner: "filter messages with validated symptom/severity indicators"
  input: D_microblogs, F_symptom_features
  output: D_illness_events
  actor: hybrid
  description: "Retain only messages carrying validated illness-related
    indicators as geolocated, time-stamped illness-report events"

artifact D_illness_events : entities
  internal structure: elementary
  embedment: {space, time}
  features:
    - id: symptom_type
      value structure: atomic
      value type: categorical
      description: "Symptom type(s) mentioned"
    - id: severity
      value structure: atomic
      value type: ordinal
      description: "Severity level (mild symptom vs.
        severe/hospitalization/death mention)"
    - id: raw_text
      value structure: atomic
      value type: text
      description: "Original message text retained for drill-down"
  description: "Geolocated, time-stamped illness-report events derived from
    validated microblog messages"

# ============================================================================
# STAGE B: TEMPORAL OVERVIEW - ONSET DETECTION
# ============================================================================

transform T_define_days :
  intent: define-unit
  manner: "time-partitioning into per-zone daily episodes"
  input: D_illness_events, D_zones
  output: D_days
  actor: machine
  description: "Aggregate illness events into hourly/6-hour bins and group
    into daily episodes per zone"

artifact D_days : entities
  internal structure: episode
  embedment: {set, time}
  features:
    - id: hourly_counts
      value structure: vector
      value type: numeric
      description: "Hourly (or 6-hour) event counts within the day, per
        zone"
  description: "Per-zone daily episodes of illness-event counts"

transform T_characterise_daily_profile :
  intent: characterise
  manner: "profile"
  input: D_days
  output: F_daily_profile
  actor: machine
  description: "Normalise hourly count vectors into comparable daily shape
    profiles"

artifact F_daily_profile : feature(D_days)
  value structure: vector
  value type: numeric
  representation form: "daily count profile"
  description: "Normalized daily profile shape used for baseline-deviation
    clustering"

transform T_cluster_days :
  intent: define-unit
  manner: "cluster-by-similarity of daily profile shape"
  input: D_days, F_daily_profile
  output: D_day_clusters, F_day_cluster_label
  actor: machine
  description: "Cluster days by profile shape so that days deviating from
    the pre-outbreak baseline pattern are separated out"

artifact D_day_clusters : entities
  internal structure: group/cluster
  embedment: set
  description: "Groups of days with similar profile shape (baseline vs.
    deviating clusters)"

artifact F_day_cluster_label : feature(D_days)
  value structure: atomic
  value type: categorical
  description: "Cluster membership label (baseline vs. deviating) for each
    day"

transform T_arrange_calendar :
  intent: contextualise
  manner: "calendar-based"
  input: D_days, D_calendar
  output: A_calendar
  actor: machine
  description: "Position each per-zone daily episode in its corresponding
    calendar cell"

artifact A_calendar : arrangement(D_days)
  context: D_calendar
  principle: "calendar(date, zone)"
  description: "Calendar-based arrangement of daily episodes per zone"

transform T_vis_calendar :
  intent: visualise
  manner: "coloured-marks"
  input: A_calendar, F_day_cluster_label
  output: V_calendar_clusters
  actor: machine
  description: "Calendar view showing cluster membership (baseline vs.
    deviating) of each day, per zone"

artifact V_calendar_clusters : visualisation(A_calendar, F_day_cluster_label)
  layout: "calendar grid per zone"
  form: "coloured marks"
  encoding: "layout: from A_calendar (day -> calendar cell); colour: from
    F_day_cluster_label"
  description: "Visual overview for spotting onset day(s) and
    earliest-deviating zones"

transform T_abstract_onset :
  intent: abstract
  manner: "perception-and-interpretation"
  input: V_calendar_clusters
  output: P_onset_pattern
  actor: human
  description: "Identify the earliest day(s) and zone(s) whose profile
    breaks from the baseline pattern"

artifact P_onset_pattern : pattern(D_days)
  representation form: "textual description"
  description: "Description of onset day(s) and earliest-deviating
    zone(s)"

transform T_knowledge_onset :
  intent: generate-knowledge
  manner: "formulate-statements"
  input: P_onset_pattern
  output: K_onset_candidates
  actor: human
  description: "Formulate candidate outbreak onset time window and
    earliest zone(s) as working hypothesis for spatial origin"

artifact K_onset_candidates : knowledge(D_days)
  representation form: "statements"
  description: "Candidate onset time window and earliest-affected zone(s),
    to be confirmed against place-level evidence"

# ============================================================================
# STAGE C: SPATIAL HOTSPOT / SIGNIFICANT-PLACE EXTRACTION
# ============================================================================

transform T_define_places :
  intent: define-unit
  manner: "derive-places (spatio-temporal density clustering)"
  input: D_illness_events
  output: D_places, F_place_membership
  actor: machine
  description: "Cluster illness events jointly by spatial and temporal
    proximity into candidate significant places, treating isolated events
    as noise"

artifact D_places : entities
  internal structure: group/cluster
  embedment: space
  features:
    - id: place_extent
      value structure: atomic
      value type: spatial
      description: "Spatial hull/buffer delineating the place"
    - id: onset_time
      value structure: atomic
      value type: temporal
      description: "Earliest event time within the place cluster"
  description: "Candidate significant places (spatio-temporal event
    clusters) derived from illness events"

artifact F_place_membership : feature(D_illness_events)
  value structure: atomic
  value type: reference
  description: "Assignment of each illness event to a place cluster (or
    noise)"

transform T_characterise_place_timeseries :
  intent: characterise
  manner: "aggregate"
  input: D_places, D_illness_events, F_place_membership
  output: F_place_timeseries
  actor: machine
  description: "Compute per-place time series of event counts"

artifact F_place_timeseries : feature(D_places)
  value structure: vector
  value type: numeric
  representation form: "time series per place"
  description: "Event-count time series per candidate place"

transform T_characterise_place_incidence :
  intent: characterise
  manner: "normalise by population"
  input: D_places, D_zones, F_place_timeseries
  output: F_place_incidence
  actor: machine
  description: "Normalise place-level event counts by zone population to
    obtain per-capita incidence"

artifact F_place_incidence : feature(D_places)
  value structure: vector
  value type: numeric
  description: "Per-capita incidence time series per place"

transform T_arrange_map_places :
  intent: contextualise
  manner: "map-based"
  input: D_places, D_map_features
  output: A_map_places
  actor: machine
  description: "Overlay candidate places on the map context (highways,
    hospitals, landmarks, water bodies)"

artifact A_map_places : arrangement(D_places)
  context: D_map_features
  principle: "geographic coordinates"
  description: "Spatial arrangement of candidate places relative to map
    features"

transform T_vis_map_hotspots :
  intent: visualise
  manner: "coloured-marks"
  input: A_map_places, F_place_incidence, D_map_features
  output: V_map_hotspots
  actor: machine
  description: "Map view of candidate places sized/coloured by onset time
    and per-capita incidence, overlaid on landmarks and water bodies"

artifact V_map_hotspots : visualisation(A_map_places, F_place_incidence,
    D_map_features)
  layout: "geographic map"
  form: "coloured marks with size/time encoding"
  encoding: "position: from A_map_places; colour/size: from
    F_place_incidence and onset_time; background: D_map_features"
  description: "Visual identification of the earliest and most severe
    place cluster(s) and their co-location with fixed landmarks"

transform T_abstract_origin_candidate :
  intent: abstract
  manner: "perception-and-interpretation"
  input: V_map_hotspots
  output: P_origin_candidate
  actor: human
  description: "Identify candidate origin place(s) and note whether they
    coincide with a specific fixed feature (e.g., reservoir, festival
    ground) versus diffuse residential spread"

artifact P_origin_candidate : pattern(D_places)
  representation form: "textual description"
  description: "Candidate origin place(s), their co-location with map
    features, and earliest onset time"

# ============================================================================
# STAGE D: SPATIO-TEMPORAL GROUPING AND GROWTH MODELLING ACROSS ZONES
# ============================================================================

transform T_characterise_zone_incidence :
  intent: characterise
  manner: "aggregate and normalise by population"
  input: D_zones, D_illness_events
  output: F_zone_incidence
  actor: machine
  description: "Compute per-capita incidence time series for each of the
    13 zones"

artifact F_zone_incidence : feature(D_zones)
  value structure: vector
  value type: numeric
  representation form: "time series per zone"
  description: "Daily per-capita incidence time series per zone"

transform T_cluster_zones :
  intent: define-unit
  manner: "cluster-by-similarity of incidence profile"
  input: D_zones, F_zone_incidence
  output: D_zone_groups, F_zone_group_label
  actor: machine
  description: "Group the 13 zones by similarity of their temporal
    incidence profile"

artifact D_zone_groups : entities
  internal structure: group/cluster
  embedment: space
  description: "Groups of zones with similar temporal incidence profiles"

artifact F_zone_group_label : feature(D_zones)
  value structure: atomic
  value type: categorical
  description: "Temporal-similarity group label for each zone"

transform T_arrange_map_zones :
  intent: contextualise
  manner: "map-based"
  input: D_zones, D_map_features
  output: A_map_zones
  actor: machine
  description: "Position zones on the map context, including the highway
    network"

artifact A_map_zones : arrangement(D_zones)
  context: D_map_features
  principle: "geographic coordinates"
  description: "Spatial arrangement of zones relative to highways and
    other map features"

transform T_vis_zone_groups :
  intent: visualise
  manner: "coloured-marks"
  input: A_map_zones, F_zone_group_label, D_map_features
  output: V_zone_groups_map
  actor: machine
  description: "Map view of zones coloured by temporal-similarity group,
    overlaid on the highway network, to check spatial contiguity versus
    dispersion"

artifact V_zone_groups_map : visualisation(A_map_zones, F_zone_group_label,
    D_map_features)
  layout: "geographic map"
  form: "coloured region marks"
  encoding: "position: from A_map_zones; colour: from F_zone_group_label;
    background: highway layer from D_map_features"
  description: "Visual check of whether temporally similar zones are
    spatially contiguous/highway-aligned or spatially disconnected"

transform T_build_growth_model :
  intent: build-model
  manner: "fit-growth-curve"
  input: F_zone_incidence, D_zone_groups
  output: M_growth
  actor: machine
  description: "Fit an exponential/logistic growth curve to each zone
    group's representative incidence curve"

artifact M_growth : model(F_zone_incidence, D_zone_groups)
  model type: "growth model"
  representation form: "exponential/logistic curve parameters per group"
  description: "Simple growth model of outbreak onset/expansion per zone
    group"

transform T_characterise_residuals :
  intent: characterise
  manner: "compute-statistics (residuals)"
  input: F_zone_incidence, M_growth
  output: F_growth_residuals
  actor: machine
  description: "Compute residuals of observed incidence relative to the
    fitted group growth curve, to flag zones deviating from the dominant
    pattern"

artifact F_growth_residuals : feature(D_zones)
  value structure: vector
  value type: numeric
  description: "Residual time series per zone relative to fitted growth
    model"

transform T_vis_residuals :
  intent: visualise
  manner: "line-graph / coloured-marks on map"
  input: F_growth_residuals, A_map_zones
  output: V_residuals_map
  actor: machine
  description: "Map and/or timeline view highlighting zones with large
    residuals (candidates for a distinct secondary source or delayed
    exposure)"

artifact V_residuals_map : visualisation(F_growth_residuals, A_map_zones)
  layout: "geographic map / aligned timelines"
  form: "coloured marks / line graph"
  encoding: "colour or line deviation: from F_growth_residuals; position:
    from A_map_zones"
  description: "Highlights zones whose incidence deviates from the
    dominant growth pattern"

transform T_abstract_spread_pattern :
  intent: abstract
  manner: "perception-and-interpretation"
  input: V_zone_groups_map, V_residuals_map, D_map_features
  output: P_spread_pattern
  actor: human
  description: "Interpret whether zone grouping follows the
    highway/mobility network (favouring person-to-person spread) or is
    spatially disconnected (favouring a shared, non-contact exposure);
    flag deviating zones as candidate secondary sources"

artifact P_spread_pattern : pattern(D_zone_groups, F_growth_residuals)
  representation form: "textual description"
  description: "Description of the dominant spread geometry
    (contiguous/highway-aligned vs. disconnected) and any deviating zones"

# ============================================================================
# STAGE E: WIND-SPREAD CROSS-IMPACT ANALYSIS (AIRBORNE HYPOTHESIS)
# ============================================================================

transform T_characterise_downwind_alignment :
  intent: characterise
  manner: "compute directional alignment relative to wind"
  input: D_zones, D_weather, P_origin_candidate
  output: F_downwind_alignment
  actor: machine
  description: "For each zone and day, compute how well the zone's bearing
    from the candidate origin matches that day's wind direction"

artifact F_downwind_alignment : feature(D_zones)
  value structure: vector
  value type: numeric
  description: "Daily downwind alignment score per zone relative to the
    candidate origin place"

artifact S_lag_spec : specification
  origin: given
  representation form: "parameter settings"
  description: "Initial window length, lag range, and tolerance interval
    for cross-impact analysis between wind and incidence/alignment
    series"

loop L_wind_analysis:
  purpose: "Compute and calibrate the wind-incidence cross-impact pattern
    to test the airborne transmission hypothesis"
  until: "Impact matrix is stable/interpretable enough to support a
    judgment on the airborne hypothesis"
  body:

    transform T_define_lag_windows :
      intent: define-unit
      manner: "time-partitioning into sliding windows"
      input: D_weather, F_zone_incidence, S_lag_spec
      output: D_windows
      actor: machine
      description: "Partition the wind series and each zone's response
        series into sliding comparison windows over a range of plausible
        incubation lags"

    artifact D_windows : entities
      internal structure: episode
      embedment: time
      features:
        - id: lag
          value structure: atomic
          value type: numeric
          description: "Lag offset applied when comparing base and
            response series in this window"
      description: "Sliding time windows used to compare the wind (base)
        series with each zone's response series at varying lags"

    transform T_characterise_cross_impact :
      intent: characterise
      manner: "compute lagged association (tolerance-based)"
      input: D_windows, D_weather, F_zone_incidence, F_downwind_alignment,
             S_lag_spec
      output: F_impact_matrix
      actor: machine
      description: "Compute a tolerance-based association measure (e.g.,
        tolerance-Kendall's-tau) between the wind base series and each
        zone's response series across the window/lag grid"

    artifact F_impact_matrix : feature(D_zones)
      value structure: matrix
      value type: numeric
      representation form: "time x lag impact matrix (Ikat-style)"
      description: "Per-zone matrix of association strength across time
        windows and lags"

    transform T_vis_impact :
      intent: visualise
      manner: "matrix-plot"
      input: F_impact_matrix
      output: V_wind_impact
      actor: machine
      description: "Ikat-style visualisation of the time x lag impact
        matrix for each zone (or aggregated downwind vs. upwind
        comparison)"

    artifact V_wind_impact : visualisation(F_impact_matrix)
      layout: "time x lag grid, per zone"
      form: "matrix plot"
      encoding: "cell colour: from F_impact_matrix association strength"
      description: "Visual display for inspecting whether downwind zones
        show a consistent positive impact at a plausible lag"

    transform T_assess_impact :
      intent: assess
      manner: "evaluate stability and interpretability of impact pattern"
      input: V_wind_impact, D_weather, F_zone_incidence
      output: K_impact_quality
      actor: human
      description: "Judge whether the current window/lag/tolerance
        settings yield a stable, interpretable impact pattern,
        cross-checking suspicious cells against the underlying wind and
        incidence series"

    artifact K_impact_quality : knowledge(F_impact_matrix)
      representation form: "quality judgment"
      description: "Judgment of whether the impact matrix is
        stable/interpretable or requires recalibration of parameters"

    if K_impact_quality indicates refinement needed:
      then:
        transform T_refine_lag_spec :
          intent: generate-knowledge
          manner: "adjust parameter settings"
          input: K_impact_quality, S_lag_spec
          output: S_lag_spec_r
          actor: human
          description: "Adjust window length, lag range, or tolerance
            based on assessment"

        artifact S_lag_spec_r : specification
          representation form: "parameter settings"
          description: "Revised window/lag/tolerance settings"

        assign:
          S_lag_spec := S_lag_spec_r
      else:
        exit loop L_wind_analysis

end loop L_wind_analysis

transform T_knowledge_airborne :
  intent: generate-knowledge
  manner: "formulate-statements"
  input: V_wind_impact, F_impact_matrix
  output: K_airborne_evidence
  actor: human
  description: "Formulate a statement on whether downwind zones show a
    consistent lagged impact from wind at the candidate origin, supporting
    or refuting airborne transmission"

artifact K_airborne_evidence : knowledge(F_impact_matrix)
  representation form: "statements"
  description: "Evidence for or against airborne transmission based on
    stable directional wind-lag association"

# ============================================================================
# STAGE F: PERSON-TO-PERSON AND WATERBORNE HYPOTHESIS CHECKS
# ============================================================================

transform T_characterise_social_mentions :
  intent: characterise
  manner: "extract (co-location/social mentions from text)"
  input: D_illness_events
  output: F_social_mentions
  actor: hybrid
  description: "Extract mentions of shared social context (coworkers,
    family, shared venues, shared transit lines) from illness-event text"

artifact F_social_mentions : feature(D_illness_events)
  value structure: list
  value type: {text, categorical}
  description: "Extracted social/co-location references per illness
    event"

transform T_define_social_network :
  intent: define-unit
  manner: "derive relational structure from co-occurrence mentions"
  input: D_illness_events, F_social_mentions
  output: D_social_network
  actor: hybrid
  description: "Build a light co-occurrence network of people/places
    mentioned together across illness events"

artifact D_social_network : entities
  internal structure: formation
  features:
    - id: edge_weight
      value structure: atomic
      value type: numeric
      description: "Strength of co-occurrence link"
  description: "Co-occurrence network of persons/places mentioned together
    in illness reports (single relational structure)"

transform T_vis_social_network :
  intent: visualise
  manner: "node-link-diagram"
  input: D_social_network
  output: V_social_network
  actor: machine
  description: "Node-link visualisation of the social/co-location
    co-occurrence network"

artifact V_social_network : visualisation(D_social_network)
  layout: "force-directed network layout"
  form: "node-link diagram"
  encoding: "edges: from D_social_network edge_weight"
  description: "Visualisation for inspecting chains of social/mobility
    contact among cases"

transform T_abstract_p2p_pattern :
  intent: abstract
  manner: "perception-and-interpretation"
  input: V_social_network, V_zone_groups_map
  output: P_p2p_pattern
  actor: human
  description: "Assess whether cases chain along social/mobility links and
    whether spatial growth tracks the highway/transit network rather than
    a single fixed landmark"

artifact P_p2p_pattern : pattern(D_social_network, D_zone_groups)
  representation form: "textual description"
  description: "Description of evidence for/against person-to-person
    transmission via social and mobility chains"

transform T_vis_water_overlay :
  intent: visualise
  manner: "map-based overlay"
  input: A_map_places, D_map_features
  output: V_water_overlay
  actor: machine
  description: "Overlay origin and hotspot clusters directly on the
    water-body layer and any known water-service-area boundaries"

artifact V_water_overlay : visualisation(A_map_places, D_map_features)
  layout: "geographic map"
  form: "coloured marks over water/service-area layer"
  encoding: "hotspot marks: from A_map_places; background: water
    bodies/service areas from D_map_features"
  description: "Visual check of whether hotspot clusters are coincident
    with water sources or service-area boundaries"

transform T_abstract_waterborne_pattern :
  intent: abstract
  manner: "perception-and-interpretation"
  input: V_water_overlay, P_origin_candidate
  output: P_waterborne_pattern
  actor: human
  description: "Assess whether the origin/hotspot clusters coincide with a
    water source and whether case distribution matches water-service areas
    rather than road proximity or social chains"

artifact P_waterborne_pattern : pattern(D_places)
  representation form: "textual description"
  description: "Description of evidence for/against waterborne
    transmission"

transform T_knowledge_mechanism_checklist :
  intent: generate-knowledge
  manner: "formulate-statements (comparison checklist)"
  input: K_airborne_evidence, P_p2p_pattern, P_waterborne_pattern,
         P_spread_pattern
  output: K_mechanism_assessment
  actor: human
  description: "Compile a diagnostic checklist comparing the expected
    spatial/temporal/contextual signature of each transmission mechanism
    (airborne, person-to-person, waterborne) against the observed
    evidence"

artifact K_mechanism_assessment : knowledge(K_airborne_evidence,
    P_p2p_pattern, P_waterborne_pattern, P_spread_pattern)
  representation form: "comparison checklist / statements"
  description: "Structured comparison of candidate transmission
    mechanisms against observed diagnostic signatures"

# ============================================================================
# STAGE G: SYNTHESIS AND REPORTING
# ============================================================================

transform T_synthesise_report :
  intent: generate-knowledge
  manner: "write-summary"
  input: K_onset_candidates, P_origin_candidate, K_mechanism_assessment
  output: K_final_report
  actor: human
  description: "Synthesise the probable origin place and time window, the
    dominant spread pattern, and the best-supported transmission mechanism
    into an evidence-linked report for emergency management"

artifact K_final_report : knowledge(D_places, D_zone_groups,
    F_impact_matrix)
  representation form: "statements / report"
  description: "Evidence-linked report on outbreak origin, spread pattern,
    and most probable transmission mechanism, to guide deployment of
    emergency management resources"