Skip to content

[Sad Catapella B9][Mask reporting] Cyclic mask hierarchies are rendered as empty or truncated trees without warning #105

Closed

Description

@guijacquemet

Source baseline and classification

Final Batch 9, pinned d7a538e56d41ac1093ba79adcad397c21b3dfd32. Confirmed report failure for a cyclic hierarchy input, with genuine cycle occurrence in scanner outputs an unverified edge case. No runtime tests executed.

Evidence

  • MaskReport.hierarchy lines 176–183 materializes a directed mapping of child -> direct parents, without acyclicity enforcement.
  • _relations() lines 502–519 marks an edge direct if it is not a two-step implied edge. It does not check full-graph cycles; aggregate pair relations are built from pairwise evidence across images. Pairwise cooccurrence can differ from image to image.
  • _hierarchy_lines() lines 442–457 only starts traversal at nodes with no parents and recursively follows children without a visited set. A cycle A→B→C→A has no root, so the report silently prints no mask types under 'Hierarchy (direct parents only)'. If a malicious/custom MaskReport contains a cycle reachable from a root, recursion can fail; whether the scanner can produce that exact topology is unproven.
  • mask_report_summary() lines 387–420 displays that hierarchy as if complete; no cycle diagnostic.

Impact

Silently incomplete mask relationship reporting and false reassurance that no hierarchy exists. The JSON hierarchy retains the edges but is not flagged as cyclic. This is distinct from #67 (incorrect one-to-one matching) and #69 (performance).

Fix and acceptance

Validate that the proposed hierarchy is a DAG (or represent cycles as explicit ambiguous relationships); never silently omit nodes. On detected cycle, present every involved type and edge with a warning that a biological parent-child hierarchy cannot be inferred, and still list all mask types. Consider a condensation graph (strongly connected components) for presentation, not automatic biological direction guessing. Add direct MaskReport A↔B and A→B→C→A fixtures, a valid DAG, multiple-parent DAG, and an end-to-end scan fixture with pairwise sparse co-occurrence if it genuinely yields a cycle. Do not presume a hierarchy that the evidence does not support. No Numba role.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions