Skip to main content

Chapter 41
Visual Cortex Engine

Part IX Perceptual Engines
Authors: Mark Anthony Higgins
and Sky Recursive Ai
© Mark Anthony Higgins 11 October 2025
Revised Date: 19 July 2026
Audio Overview
flow "Visual_Cortex_Engine" v1.0

# =============================================================================
# CHAPTER 41 — VISUAL CORTEX ENGINE
# PART IX — PERCEPTUAL ENGINES
# =============================================================================
#
# EXECUTION CLASS:
#     Full executable perceptual-engine Flow Algebra
#
# EXCLUDED CLASS:
#     AI Search Flow
#     Metadata representation
#     Search-engine semantic specification
#     Crawler-facing page summary
#
# PRIMARY PURPOSE:
#
#     Transform incoming visual energy into a recursively stabilised,
#     spatially organised, temporally persistent and semantically meaningful
#     internal visual field.
#
# CENTRAL EXECUTION CHAIN:
#
#     Optical Input
#         →
#     Sensory Boundary Registration
#         →
#     Retinal Encoding
#         →
#     Contrast and Edge Extraction
#         →
#     Orientation and Motion Mapping
#         →
#     Depth and Colour Reconstruction
#         →
#     Feature Binding
#         →
#     Object Hypothesis Formation
#         →
#     Predictive Scene Reconstruction
#         →
#     Recursive Error Correction
#         →
#     Coherent Visual Field
#         →
#     Memory and Action Integration
#
# FOUNDATIONAL PRINCIPLE:
#
#     Vision is not passive image capture.
#
#     Vision is the recursive reconstruction of a probable external scene
#     from incomplete, noisy, temporally changing boundary signals.
#
# =============================================================================


# =============================================================================
# 0. EXECUTION DECLARATION
# =============================================================================

EXECUTION_MODE              := "continuous_recursive_perception"
ENGINE_DOMAIN               := "visual_cortex"
PERCEPTUAL_MODALITY         := "vision"
PROCESSING_DIRECTION        := {
    BOTTOM_UP,
    TOP_DOWN,
    RECURRENT,
    LATERAL
}

INPUT_MODE                  := "spatiotemporal_photonic_signal"
OUTPUT_MODE                 := "coherent_visual_scene"
TEMPORAL_MODE               := "streaming"
RECURSION_MODE              := "bounded_predictive"
ATTENTION_MODE              := "dynamic"
MEMORY_INTEGRATION          := true
MULTIMODAL_INTEGRATION      := true
ACTION_COUPLING             := true
CONSCIOUS_ACCESS_OPTIONAL   := true
HALLUCINATION_GUARD         := true
UNCERTAINTY_TRACKING        := true
IDENTITY_PROTECTION         := true
ETHICAL_PERCEPTION_FILTER   := false

# Ethical perception filtering is false because the engine must not alter
# incoming evidence merely because the evidence is uncomfortable.
#
# Ethical constraints apply to:
#     storage,
#     interpretation,
#     disclosure,
#     use,
#     action,
#
# but not to the faithful registration of sensory evidence.


# =============================================================================
# 1. TYPE SYSTEM
# =============================================================================

type PixelIndex             := integer
type FrameIndex             := integer
type ChannelIndex           := integer
type LayerIndex             := integer
type ObjectID               := string
type TrackID                := string
type SceneID                := string
type RegionID               := string
type FeatureID              := string
type HypothesisID           := string
type Timestamp              := real
type Duration               := real
type Scalar                 := real
type Probability            := real[0.0,1.0]
type Confidence             := real[0.0,1.0]
type CoherenceScore         := real[0.0,1.0]
type SalienceScore          := real[0.0,1.0]
type AttentionWeight        := real[0.0,1.0]
type ErrorMagnitude         := real[0.0,1.0]
type Uncertainty            := real[0.0,1.0]
type Luminance              := real[0.0,1.0]
type ChromaticValue         := real[0.0,1.0]
type DepthValue             := real
type Velocity               := vector[2,real]
type Position2D             := vector[2,real]
type Position3D             := vector[3,real]
type Vector2                := vector[2,real]
type Vector3                := vector[3,real]
type Matrix                 := matrix[real]
type Tensor                 := tensor[real]
type Boolean                := true | false


enum EyeSource {
    LEFT_EYE,
    RIGHT_EYE,
    MONOCULAR_SENSOR,
    STEREO_SENSOR,
    SYNTHETIC_SENSOR,
    UNKNOWN_SENSOR
}


enum FeatureType {
    LUMINANCE,
    CONTRAST,
    EDGE,
    ORIENTATION,
    CORNER,
    CURVATURE,
    TEXTURE,
    COLOUR,
    DEPTH,
    MOTION,
    FLOW,
    OCCLUSION,
    SYMMETRY,
    SHAPE,
    FACE_PATTERN,
    BODY_PATTERN,
    TEXT_PATTERN,
    UNKNOWN
}


enum MotionClass {
    STATIC,
    TRANSLATING,
    ROTATING,
    EXPANDING,
    CONTRACTING,
    DEFORMING,
    OCCLUDED,
    UNKNOWN_MOTION
}


enum ObjectState {
    CANDIDATE,
    DETECTED,
    BOUND,
    TRACKED,
    OCCLUDED,
    LOST,
    REIDENTIFIED,
    REJECTED
}


enum SceneStatus {
    UNINITIALISED,
    PARTIAL,
    STABLE,
    UNSTABLE,
    AMBIGUOUS,
    CONTRADICTORY,
    HALLUCINATED,
    DEGRADED
}


enum PredictionSource {
    LOCAL_VISUAL_HISTORY,
    OBJECT_MEMORY,
    SCENE_MEMORY,
    SEMANTIC_MEMORY,
    MOTOR_EFFERENCE,
    MULTIMODAL_CONTEXT,
    UNKNOWN_SOURCE
}


enum FailureClass {
    NONE,
    INPUT_LOSS,
    SENSOR_SATURATION,
    RETINAL_ENCODING_FAILURE,
    FEATURE_EXTRACTION_FAILURE,
    BINDING_FAILURE,
    DEPTH_FAILURE,
    MOTION_FAILURE,
    OBJECT_CONFUSION,
    TRACKING_FAILURE,
    SCENE_FRAGMENTATION,
    PREDICTION_DOMINANCE,
    HALLUCINATION,
    MEMORY_CONTAMINATION,
    ATTENTION_COLLAPSE,
    TEMPORAL_DISCONTINUITY,
    CONFIDENCE_INFLATION,
    UNKNOWN_FAILURE
}


# =============================================================================
# 2. DATA STRUCTURES
# =============================================================================

record PhotoreceptorSample {
    eye_source: EyeSource
    pixel_position: Position2D
    timestamp: Timestamp

    wavelength_response: vector[real]
    luminance: Luminance
    saturation: Scalar
    noise_level: Scalar
    valid: Boolean
}


record VisualFrame {
    frame_index: FrameIndex
    timestamp: Timestamp
    width: integer
    height: integer

    left_input: Tensor?
    right_input: Tensor?
    auxiliary_channels: map[string,Tensor]
    exposure: Scalar
    sensor_noise: Scalar
    valid_region_mask: Matrix
}


record RetinalField {
    timestamp: Timestamp

    luminance_field: Matrix
    colour_opponent_field: Tensor
    centre_surround_field: Tensor
    local_contrast_field: Matrix
    transient_field: Matrix
    sustained_field: Matrix

    valid_mask: Matrix
    retinal_confidence: Confidence
}


record ReceptiveField {
    field_id: string
    centre: Position2D
    radius: Scalar
    orientation_preference: Scalar?
    spatial_frequency: Scalar?
    temporal_frequency: Scalar?
    channel_preference: FeatureType
}


record FeatureActivation {
    feature_id: FeatureID
    feature_type: FeatureType

    position: Position2D
    scale: Scalar
    orientation: Scalar?
    magnitude: Scalar
    temporal_phase: Scalar
    confidence: Confidence

    source_frame: FrameIndex
    parent_features: set[FeatureID]
}


record FeatureMap {
    feature_type: FeatureType
    scale: Scalar
    timestamp: Timestamp

    activation_tensor: Tensor
    confidence_tensor: Tensor
    uncertainty_tensor: Tensor
}


record MotionVector {
    position: Position2D
    velocity: Velocity
    acceleration: Velocity
    confidence: Confidence
    motion_class: MotionClass
}


record DepthEstimate {
    position: Position2D
    depth: DepthValue
    disparity: Scalar?
    monocular_support: Scalar
    binocular_support: Scalar
    confidence: Confidence
}


record BoundarySegment {
    segment_id: string
    points: list[Position2D]
    orientation_profile: list[Scalar]
    curvature_profile: list[Scalar]
    closure_score: Scalar
    continuity_score: Scalar
    confidence: Confidence
}


record SurfaceRegion {
    region_id: RegionID
    boundary_segments: set[string]
    interior_points: set[Position2D]

    mean_colour: Vector3
    texture_signature: Tensor
    depth_profile: list[DepthEstimate]
    motion_profile: list[MotionVector]

    surface_coherence: CoherenceScore
    confidence: Confidence
}


record ObjectHypothesis {
    hypothesis_id: HypothesisID
    object_id: ObjectID?

    supporting_features: set[FeatureID]
    supporting_regions: set[RegionID]
    boundary_segments: set[string]

    estimated_position_2d: Position2D
    estimated_position_3d: Position3D?
    estimated_shape: Tensor
    estimated_colour: Vector3
    estimated_texture: Tensor
    estimated_motion: MotionVector

    category_distribution: map[string,Probability]
    identity_distribution: map[string,Probability]

    occlusion_fraction: Scalar
    object_coherence: CoherenceScore
    confidence: Confidence
    uncertainty: Uncertainty
    state: ObjectState
}


record ObjectTrack {
    track_id: TrackID
    object_id: ObjectID?
    state_history: list[ObjectHypothesis]

    current_position: Position3D?
    current_velocity: Velocity
    predicted_position: Position3D?
    visibility: Scalar
    persistence_score: Scalar
    confidence: Confidence
    state: ObjectState
}


record AttentionTarget {
    target_id: string
    spatial_region: RegionID?
    object_id: ObjectID?
    feature_type: FeatureType?

    bottom_up_salience: SalienceScore
    top_down_relevance: SalienceScore
    uncertainty_priority: SalienceScore
    threat_priority: SalienceScore
    task_priority: SalienceScore

    total_weight: AttentionWeight
}


record VisualPrediction {
    prediction_id: string
    source: PredictionSource
    target_layer: string

    predicted_features: list[FeatureActivation]
    predicted_objects: list[ObjectHypothesis]
    predicted_scene_state: map[string,any]

    confidence: Confidence
    temporal_horizon: Duration
}


record PredictionError {
    error_id: string
    target_layer: string

    observed_state: any
    predicted_state: any
    residual: any

    magnitude: ErrorMagnitude
    precision: Confidence
    weighted_error: Scalar
    explanatory_status: string
}


record SpatialRelation {
    source_object: ObjectID
    predicate: string
    target_object: ObjectID

    relative_position: Vector3
    relative_depth: Scalar
    confidence: Confidence
}


record SceneGraph {
    scene_id: SceneID
    timestamp: Timestamp

    objects: map[ObjectID,ObjectHypothesis]
    relations: list[SpatialRelation]
    background_regions: set[RegionID]
    observer_pose: map[string,any]

    scene_coherence: CoherenceScore
    scene_confidence: Confidence
    scene_uncertainty: Uncertainty
    status: SceneStatus
}


record VisualMemoryTrace {
    trace_id: string
    timestamp: Timestamp

    object_signatures: map[ObjectID,Tensor]
    scene_signature: Tensor
    attended_regions: list[RegionID]
    prediction_errors: list[PredictionError]

    consolidation_weight: Scalar
    retrieval_confidence: Confidence
}


record VisualWorkspaceState {
    timestamp: Timestamp
    frame_index: FrameIndex

    retinal_field: RetinalField
    feature_maps: map[FeatureType,list[FeatureMap]]
    motion_field: list[MotionVector]
    depth_field: list[DepthEstimate]

    boundaries: list[BoundarySegment]
    surfaces: list[SurfaceRegion]
    object_hypotheses: list[ObjectHypothesis]
    object_tracks: list[ObjectTrack]

    attention_targets: list[AttentionTarget]
    predictions: list[VisualPrediction]
    prediction_errors: list[PredictionError]

    scene_graph: SceneGraph
    global_visual_coherence: CoherenceScore
    failure_class: FailureClass
}


# =============================================================================
# 3. INPUT INTERFACE
# =============================================================================

input VISUAL_STREAM              : stream[VisualFrame]
input PRIOR_VISUAL_MEMORY        : list[VisualMemoryTrace]
input OBJECT_MEMORY              : map[ObjectID,Tensor]
input SEMANTIC_MEMORY            : map[string,any]
input CURRENT_TASK               : map[string,any]?
input MOTOR_EFFERENCE_COPY       : map[string,any]?
input HEAD_POSE                  : map[string,any]?
input EYE_POSE                   : map[string,any]?
input AUDITORY_CONTEXT           : map[string,any]?
input SOMATOSENSORY_CONTEXT      : map[string,any]?
input INTERNAL_STATE             : map[string,any]?
input SAFETY_CONSTRAINTS         : map[string,any]
input MAX_RECURSION_DEPTH        : integer
input MAX_OBJECT_HYPOTHESES      : integer
input MAX_TRACK_COUNT            : integer
input FRAME_TIME_BUDGET          : Duration


# =============================================================================
# 4. OUTPUT INTERFACE
# =============================================================================

output CURRENT_VISUAL_SCENE      : SceneGraph
output ACTIVE_OBJECT_TRACKS      : list[ObjectTrack]
output VISUAL_WORKSPACE          : VisualWorkspaceState
output VISUAL_MEMORY_UPDATE      : VisualMemoryTrace
output ACTION_RELEVANT_SIGNALS   : map[string,any]
output PERCEPTUAL_UNCERTAINTIES  : list[PredictionError]
output EXECUTION_REPORT          : map[string,any]


# =============================================================================
# 5. GLOBAL THRESHOLDS
# =============================================================================

constant THETA_INPUT_VALID             : Confidence      := 0.50
constant THETA_RETINAL_CONFIDENCE      : Confidence      := 0.60
constant THETA_FEATURE_ACTIVATION      : Scalar          := 0.20
constant THETA_EDGE_CONFIDENCE         : Confidence      := 0.55
constant THETA_BOUNDARY_CONTINUITY     : Scalar          := 0.60
constant THETA_SURFACE_COHERENCE       : CoherenceScore  := 0.62
constant THETA_OBJECT_COHERENCE        : CoherenceScore  := 0.68
constant THETA_OBJECT_ACCEPTANCE       : Confidence      := 0.65
constant THETA_TRACK_PERSISTENCE       : Scalar          := 0.55
constant THETA_SCENE_COHERENCE         : CoherenceScore  := 0.72
constant THETA_CONSCIOUS_ACCESS        : CoherenceScore  := 0.80
constant THETA_PREDICTION_ERROR        : ErrorMagnitude  := 0.25
constant THETA_HALLUCINATION_RISK      : Scalar          := 0.45
constant THETA_OCCLUSION_RETENTION     : Confidence      := 0.60
constant THETA_REIDENTIFICATION        : Confidence      := 0.75
constant THETA_MEMORY_CONSOLIDATION    : Confidence      := 0.70

constant MAX_PREDICTION_DOMINANCE      : Scalar          := 0.55
constant MAX_UNSUPPORTED_OBJECTS       : integer         := 3
constant MAX_SCENE_UNCERTAINTY         : Uncertainty     := 0.45
constant MAX_TEMPORAL_GAP              : Duration        := 0.25
constant MAX_FRAME_RECURSIONS          : integer         := 8
constant MAX_BINDING_ITERATIONS        : integer         := 6
constant MAX_SCENE_REVISIONS           : integer         := 5


# =============================================================================
# 6. FOUNDATIONAL INVARIANTS
# =============================================================================

invariant V01_SENSORY_EVIDENCE_PRIORITY:

    observed_visual_evidence
        must_not_be_overwritten_by
        unsupported_prediction


invariant V02_PREDICTION_IS_HYPOTHESIS:

    every top_down_prediction must remain:
        weighted
        revisable
        uncertainty_marked
        evidence_constrained


invariant V03_NO_OBJECT_WITHOUT_SUPPORT:

    require accepted_object.supporting_features is not empty
        or accepted_object.supporting_regions is not empty
        or accepted_object.confidence is explicitly marked as inferred


invariant V04_TEMPORAL_CONTINUITY:

    visual_identity_persistence
        requires
    cross_frame_support
        or
    bounded_occlusion_prediction


invariant V05_BINDING_CONSISTENCY:

    one feature activation
        must_not_be_bound_to
    mutually exclusive objects
        unless ambiguity is explicitly represented


invariant V06_SPATIAL_CONSISTENCY:

    require object positions,
            depth estimates,
            boundaries,
            motion vectors
    to remain mutually satisfiable
    within uncertainty bounds


invariant V07_CONFIDENCE_CALIBRATION:

    confidence must decrease when:
        evidence decreases
        contradiction increases
        occlusion increases
        temporal discontinuity increases
        prediction error increases


invariant V08_HALLUCINATION_GUARD:

    prohibit stable_scene_commit
    when:
        top_down_support > sensory_support
        and prediction_error remains high
        and external evidence is insufficient


invariant V09_MEMORY_NON_CONTAMINATION:

    prohibit long_term_memory_consolidation
    for unsupported or hallucination-classified objects


invariant V10_ATTENTION_NON_ERASURE:

    unattended regions may receive reduced processing
    but must not be classified as nonexistent solely because unattended


invariant V11_MULTI_HYPOTHESIS_PRESERVATION:

    when two interpretations remain comparably probable:

        preserve both interpretations
        mark ambiguity
        prevent premature collapse


invariant V12_SCENE_REVISION:

    any committed scene may be revised
    when new evidence invalidates its causal structure


invariant V13_ACTION_SAFETY:

    low-confidence visual inference
        must_not_directly_trigger
    irreversible high-risk action


invariant V14_IDENTITY_SEPARATION:

    visual object identity
        must_not_be_confused_with
    observer identity


# =============================================================================
# 7. MATHEMATICAL CORE
# =============================================================================

# -----------------------------------------------------------------------------
# 7.1 Sensory field
# -----------------------------------------------------------------------------

# Let the incoming image field be:

#     I(x,y,t,c)
#
# where:
#
#     x,y = spatial position
#     t   = time
#     c   = sensory channel


function sensory_field(
    frame: VisualFrame
) -> Tensor:

    return normalise_exposure(
        remove_sensor_bias(
            merge_available_channels(frame)
        )
    )


# -----------------------------------------------------------------------------
# 7.2 Centre-surround retinal transform
# -----------------------------------------------------------------------------

# Retinal contrast response:

#     R(x,y,t)
#       =
#     [G_{\sigma_c} * I](x,y,t)
#       -
#     [G_{\sigma_s} * I](x,y,t)
#
# where:
#
#     sigma_c < sigma_s


function centre_surround(
    image: Matrix,
    sigma_centre: Scalar,
    sigma_surround: Scalar
) -> Matrix:

    require sigma_centre < sigma_surround

    return gaussian_convolve(image, sigma_centre)
         - gaussian_convolve(image, sigma_surround)


# -----------------------------------------------------------------------------
# 7.3 Oriented feature response
# -----------------------------------------------------------------------------

# For orientation theta and scale sigma:

#     F_{\theta,\sigma}
#       =
#     I * K_{\theta,\sigma}


function oriented_response(
    image: Matrix,
    orientation: Scalar,
    scale: Scalar
) -> Matrix:

    kernel :=
        generate_oriented_filter(
            orientation,
            scale
        )

    return convolve(image, kernel)


# -----------------------------------------------------------------------------
# 7.4 Motion estimation
# -----------------------------------------------------------------------------

# Optical-flow constraint:

#     I_x u + I_y v + I_t = 0


function estimate_local_motion(
    previous: Matrix,
    current: Matrix
) -> list[MotionVector]:

    spatial_x := derivative_x(current)
    spatial_y := derivative_y(current)
    temporal  := current - previous

    return solve_local_flow(
        spatial_x,
        spatial_y,
        temporal
    )


# -----------------------------------------------------------------------------
# 7.5 Binocular depth
# -----------------------------------------------------------------------------

# Approximate stereoscopic depth:

#     Z = fB / d
#
# where:
#
#     f = focal parameter
#     B = sensor baseline
#     d = binocular disparity


function binocular_depth(
    left_field: Matrix,
    right_field: Matrix,
    focal_parameter: Scalar,
    baseline: Scalar
) -> list[DepthEstimate]:

    disparities :=
        estimate_disparity(
            left_field,
            right_field
        )

    return map(
        disparities,
        d ->
            DepthEstimate(
                position          = d.position,
                depth             =
                    safe_divide(
                        focal_parameter * baseline,
                        d.disparity
                    ),
                disparity         = d.disparity,
                monocular_support = 0.0,
                binocular_support = d.confidence,
                confidence        = d.confidence
            )
    )


# -----------------------------------------------------------------------------
# 7.6 Predictive visual state
# -----------------------------------------------------------------------------

# Hierarchical prediction:

#     P_t^l = G^l(S_t^{l+1}, M_t)
#
# Prediction error:

#     epsilon_t^l = S_t^l - P_t^l
#
# Precision-weighted error:

#     epsilon_hat_t^l = Pi_t^l epsilon_t^l


function prediction_error(
    observed: any,
    predicted: any,
    precision: Confidence
) -> PredictionError:

    residual :=
        state_difference(
            observed,
            predicted
        )

    magnitude :=
        normalised_magnitude(residual)

    return PredictionError(
        error_id           = generate_error_id(),
        target_layer       = infer_target_layer(observed),
        observed_state     = observed,
        predicted_state    = predicted,
        residual           = residual,
        magnitude          = magnitude,
        precision          = precision,
        weighted_error     = magnitude * precision,
        explanatory_status = "unresolved"
    )


# -----------------------------------------------------------------------------
# 7.7 Feature-binding coherence
# -----------------------------------------------------------------------------

function binding_coherence(
    object: ObjectHypothesis
) -> CoherenceScore:

    local spatial :=
        spatial_feature_agreement(
            object.supporting_features
        )

    local temporal :=
        temporal_feature_agreement(
            object.supporting_features
        )

    local boundary :=
        boundary_support(
            object.boundary_segments
        )

    local surface :=
        surface_support(
            object.supporting_regions
        )

    local motion :=
        motion_consistency(object)

    local memory :=
        memory_shape_compatibility(object)

    local contradiction :=
        object_internal_contradiction(object)

    return clamp01(
          0.20 * spatial
        + 0.18 * temporal
        + 0.18 * boundary
        + 0.16 * surface
        + 0.12 * motion
        + 0.16 * memory
        - 0.25 * contradiction
    )


# -----------------------------------------------------------------------------
# 7.8 Scene coherence
# -----------------------------------------------------------------------------

function scene_coherence(
    scene: SceneGraph
) -> CoherenceScore:

    local object_support :=
        mean(
            map(
                values(scene.objects),
                object -> object.object_coherence
            )
        )

    local relation_support :=
        relation_consistency(scene.relations)

    local depth_support :=
        scene_depth_consistency(scene)

    local temporal_support :=
        scene_temporal_continuity(scene)

    local sensory_support :=
        scene_sensory_grounding(scene)

    local prediction_fit :=
        scene_prediction_fit(scene)

    local contradiction :=
        scene_contradiction(scene)

    return clamp01(
          0.22 * object_support
        + 0.16 * relation_support
        + 0.14 * depth_support
        + 0.16 * temporal_support
        + 0.18 * sensory_support
        + 0.14 * prediction_fit
        - 0.30 * contradiction
    )


# -----------------------------------------------------------------------------
# 7.9 Global visual coherence
# -----------------------------------------------------------------------------

function global_visual_coherence(
    retinal: RetinalField,
    features: map[FeatureType,list[FeatureMap]],
    objects: list[ObjectHypothesis],
    scene: SceneGraph,
    errors: list[PredictionError]
) -> CoherenceScore:

    local retinal_quality :=
        retinal.retinal_confidence

    local feature_quality :=
        mean_feature_confidence(features)

    local object_quality :=
        mean(
            map(
                objects,
                object -> object.object_coherence
            )
        )

    local scene_quality :=
        scene.scene_coherence

    local error_penalty :=
        mean(
            map(
                errors,
                error -> error.weighted_error
            )
        )

    return clamp01(
          0.18 * retinal_quality
        + 0.22 * feature_quality
        + 0.25 * object_quality
        + 0.35 * scene_quality
        - 0.30 * error_penalty
    )


# =============================================================================
# 8. FRAME ACQUISITION
# =============================================================================

stage ACQUIRE_VISUAL_FRAME(
    stream: stream[VisualFrame]
) -> VisualFrame:

    frame := read_next(stream)

    require frame exists
    require frame.width > 0
    require frame.height > 0

    when frame.left_input is null
         and frame.right_input is null
         and frame.auxiliary_channels is empty:

        raise INPUT_LOSS

    frame.valid_region_mask :=
        detect_valid_sensor_regions(frame)

    INPUT_CONFIDENCE :=
        compute_frame_validity(frame)

    when INPUT_CONFIDENCE < THETA_INPUT_VALID:

        frame :=
            attempt_frame_recovery(frame)

    return frame


# =============================================================================
# 9. SENSOR NORMALISATION
# =============================================================================

stage NORMALISE_VISUAL_INPUT(
    frame: VisualFrame
) -> VisualFrame:

    frame :=
        correct_dead_pixels(frame)

    frame :=
        correct_lens_distortion(frame)

    frame :=
        correct_sensor_bias(frame)

    frame :=
        stabilise_exposure(frame)

    frame :=
        estimate_sensor_noise(frame)

    frame :=
        compensate_sensor_motion(
            frame,
            HEAD_POSE,
            EYE_POSE,
            MOTOR_EFFERENCE_COPY
        )

    return frame


# =============================================================================
# 10. RETINAL ENCODING
# =============================================================================

stage ENCODE_RETINAL_FIELD(
    frame: VisualFrame
) -> RetinalField:

    RAW_FIELD :=
        sensory_field(frame)

    LUMINANCE_FIELD :=
        extract_luminance(RAW_FIELD)

    COLOUR_OPPONENT_FIELD :=
        compute_colour_opponent_channels(
            RAW_FIELD,
            channels = {
                "red_green",
                "blue_yellow",
                "light_dark"
            }
        )

    CENTRE_SURROUND_FIELD :=
        multi_scale_centre_surround(
            LUMINANCE_FIELD
        )

    LOCAL_CONTRAST_FIELD :=
        compute_local_contrast(
            LUMINANCE_FIELD
        )

    TRANSIENT_FIELD :=
        detect_temporal_change(
            LUMINANCE_FIELD
        )

    SUSTAINED_FIELD :=
        integrate_stable_signal(
            LUMINANCE_FIELD
        )

    RETINAL_CONFIDENCE :=
        retinal_quality_score(
            frame,
            LUMINANCE_FIELD,
            LOCAL_CONTRAST_FIELD
        )

    return RetinalField(
        timestamp             = frame.timestamp,
        luminance_field       = LUMINANCE_FIELD,
        colour_opponent_field = COLOUR_OPPONENT_FIELD,
        centre_surround_field = CENTRE_SURROUND_FIELD,
        local_contrast_field  = LOCAL_CONTRAST_FIELD,
        transient_field       = TRANSIENT_FIELD,
        sustained_field       = SUSTAINED_FIELD,
        valid_mask            = frame.valid_region_mask,
        retinal_confidence    = RETINAL_CONFIDENCE
    )


# =============================================================================
# 11. MULTISCALE FEATURE EXTRACTION
# =============================================================================

stage EXTRACT_PRIMITIVE_FEATURES(
    retinal: RetinalField
) -> map[FeatureType,list[FeatureMap]]:

    FEATURE_MAPS := {}

    for each scale in {
        1.0,
        2.0,
        4.0,
        8.0,
        16.0
    }:

        FEATURE_MAPS[CONTRAST] +=
            extract_contrast_map(
                retinal.local_contrast_field,
                scale
            )

        for each orientation in {
            0,
            22.5,
            45,
            67.5,
            90,
            112.5,
            135,
            157.5
        }:

            FEATURE_MAPS[ORIENTATION] +=
                build_orientation_map(
                    retinal.luminance_field,
                    orientation,
                    scale
                )

        FEATURE_MAPS[EDGE] +=
            extract_edge_map(
                retinal.luminance_field,
                scale
            )

        FEATURE_MAPS[CORNER] +=
            extract_corner_map(
                retinal.luminance_field,
                scale
            )

        FEATURE_MAPS[CURVATURE] +=
            extract_curvature_map(
                retinal.luminance_field,
                scale
            )

        FEATURE_MAPS[TEXTURE] +=
            extract_texture_map(
                retinal.luminance_field,
                scale
            )

        FEATURE_MAPS[COLOUR] +=
            extract_colour_map(
                retinal.colour_opponent_field,
                scale
            )

    FEATURE_MAPS :=
        suppress_below_threshold(
            FEATURE_MAPS,
            THETA_FEATURE_ACTIVATION
        )

    FEATURE_MAPS :=
        apply_lateral_competition(
            FEATURE_MAPS
        )

    FEATURE_MAPS :=
        preserve_multi_scale_support(
            FEATURE_MAPS
        )

    return FEATURE_MAPS


# =============================================================================
# 12. MOTION ENGINE
# =============================================================================

stage COMPUTE_MOTION_FIELD(
    previous_retinal: RetinalField?,
    current_retinal: RetinalField
) -> list[MotionVector]:

    when previous_retinal is null:

        return initialise_zero_motion_field(
            current_retinal
        )

    RAW_FLOW :=
        estimate_local_motion(
            previous_retinal.luminance_field,
            current_retinal.luminance_field
        )

    COMPENSATED_FLOW :=
        remove_observer_induced_motion(
            RAW_FLOW,
            MOTOR_EFFERENCE_COPY,
            HEAD_POSE,
            EYE_POSE
        )

    MOTION_FIELD :=
        classify_motion_patterns(
            COMPENSATED_FLOW
        )

    MOTION_FIELD :=
        enforce_local_flow_continuity(
            MOTION_FIELD
        )

    return MOTION_FIELD


# =============================================================================
# 13. DEPTH ENGINE
# =============================================================================

stage COMPUTE_DEPTH_FIELD(
    frame: VisualFrame,
    features: map[FeatureType,list[FeatureMap]],
    motion: list[MotionVector]
) -> list[DepthEstimate]:

    BINOCULAR_DEPTH := []

    when frame.left_input exists
         and frame.right_input exists:

        BINOCULAR_DEPTH :=
            binocular_depth(
                extract_luminance(frame.left_input),
                extract_luminance(frame.right_input),
                sensor_focal_parameter(frame),
                sensor_baseline(frame)
            )

    MONOCULAR_DEPTH :=
        estimate_monocular_depth_from:
            perspective(features)
            occlusion(features)
            texture_gradient(features)
            relative_size(features)
            shading(features)
            motion_parallax(motion)

    COMBINED_DEPTH :=
        precision_weighted_depth_fusion(
            BINOCULAR_DEPTH,
            MONOCULAR_DEPTH
        )

    COMBINED_DEPTH :=
        enforce_depth_discontinuity_at_boundaries(
            COMBINED_DEPTH,
            features[EDGE]
        )

    return COMBINED_DEPTH


# =============================================================================
# 14. BOUNDARY CONSTRUCTION
# =============================================================================

stage CONSTRUCT_BOUNDARIES(
    features: map[FeatureType,list[FeatureMap]],
    motion: list[MotionVector],
    depth: list[DepthEstimate]
) -> list[BoundarySegment]:

    EDGE_ELEMENTS :=
        convert_feature_maps_to_activations(
            features[EDGE]
        )

    ORIENTATION_ELEMENTS :=
        convert_feature_maps_to_activations(
            features[ORIENTATION]
        )

    CANDIDATE_SEGMENTS :=
        link_collinear_features(
            EDGE_ELEMENTS,
            ORIENTATION_ELEMENTS
        )

    CANDIDATE_SEGMENTS :=
        bridge_small_gaps(
            CANDIDATE_SEGMENTS
        )

    CANDIDATE_SEGMENTS :=
        split_at_depth_discontinuities(
            CANDIDATE_SEGMENTS,
            depth
        )

    CANDIDATE_SEGMENTS :=
        split_at_motion_discontinuities(
            CANDIDATE_SEGMENTS,
            motion
        )

    for each segment in CANDIDATE_SEGMENTS:

        segment.continuity_score :=
            compute_boundary_continuity(segment)

        segment.closure_score :=
            estimate_boundary_closure(
                segment,
                CANDIDATE_SEGMENTS
            )

        segment.confidence :=
            weighted_mean({
                feature_support(segment) : 0.40,
                continuity_score(segment): 0.25,
                depth_support(segment)   : 0.15,
                motion_support(segment)  : 0.10,
                closure_score(segment)   : 0.10
            })

    return filter(
        CANDIDATE_SEGMENTS,
        segment ->
            segment.continuity_score
                >= THETA_BOUNDARY_CONTINUITY
            and segment.confidence
                >= THETA_EDGE_CONFIDENCE
    )


# =============================================================================
# 15. SURFACE SEGMENTATION
# =============================================================================

stage FORM_SURFACES(
    retinal: RetinalField,
    features: map[FeatureType,list[FeatureMap]],
    boundaries: list[BoundarySegment],
    depth: list[DepthEstimate],
    motion: list[MotionVector]
) -> list[SurfaceRegion]:

    INITIAL_REGIONS :=
        partition_visual_field(
            boundaries
        )

    SURFACES := []

    for each region in INITIAL_REGIONS:

        surface :=
            SurfaceRegion(
                region_id         = generate_region_id(),
                boundary_segments =
                    enclosing_boundaries(region),
                interior_points   =
                    region_points(region),
                mean_colour       =
                    mean_region_colour(
                        region,
                        retinal.colour_opponent_field
                    ),
                texture_signature =
                    region_texture(
                        region,
                        features[TEXTURE]
                    ),
                depth_profile     =
                    region_depth(region, depth),
                motion_profile    =
                    region_motion(region, motion),
                surface_coherence = 0.0,
                confidence        = 0.0
            )

        surface.surface_coherence :=
            compute_surface_coherence(surface)

        surface.confidence :=
            surface.surface_coherence
            * region_evidence_strength(region)

        when surface.surface_coherence
             >= THETA_SURFACE_COHERENCE:

            SURFACES += surface

    return merge_compatible_surfaces(SURFACES)


# =============================================================================
# 16. BOTTOM-UP SALIENCE
# =============================================================================

stage COMPUTE_SALIENCE_FIELD(
    features: map[FeatureType,list[FeatureMap]],
    motion: list[MotionVector],
    depth: list[DepthEstimate],
    surfaces: list[SurfaceRegion]
) -> list[AttentionTarget]:

    SALIENCE_COMPONENTS := {
        "contrast":
            feature_distinctiveness(features[CONTRAST]),

        "colour":
            feature_distinctiveness(features[COLOUR]),

        "orientation":
            feature_distinctiveness(features[ORIENTATION]),

        "motion":
            motion_distinctiveness(motion),

        "depth":
            depth_distinctiveness(depth),

        "novelty":
            visual_novelty(
                features,
                PRIOR_VISUAL_MEMORY
            ),

        "uncertainty":
            spatial_uncertainty_map(
                features,
                depth
            )
    }

    RAW_TARGETS :=
        derive_salience_targets(
            SALIENCE_COMPONENTS,
            surfaces
        )

    return normalise_attention_targets(
        RAW_TARGETS
    )


# =============================================================================
# 17. TOP-DOWN ATTENTION
# =============================================================================

stage APPLY_TOP_DOWN_ATTENTION(
    targets: list[AttentionTarget],
    task: map[string,any]?,
    memory: map[string,any]
) -> list[AttentionTarget]:

    for each target in targets:

        target.top_down_relevance :=
            evaluate_task_relevance(
                target,
                task
            )

        target.threat_priority :=
            evaluate_immediate_hazard(
                target,
                SAFETY_CONSTRAINTS
            )

        target.task_priority :=
            evaluate_goal_priority(
                target,
                task
            )

        target.total_weight :=
            clamp01(
                  0.30 * target.bottom_up_salience
                + 0.25 * target.top_down_relevance
                + 0.20 * target.uncertainty_priority
                + 0.15 * target.threat_priority
                + 0.10 * target.task_priority
            )

    return sort_descending(
        targets,
        by = total_weight
    )


# =============================================================================
# 18. OBJECT HYPOTHESIS GENERATION
# =============================================================================

stage GENERATE_OBJECT_HYPOTHESES(
    features: map[FeatureType,list[FeatureMap]],
    boundaries: list[BoundarySegment],
    surfaces: list[SurfaceRegion],
    depth: list[DepthEstimate],
    motion: list[MotionVector],
    attention: list[AttentionTarget]
) -> list[ObjectHypothesis]:

    GROUPINGS :=
        generate_candidate_groupings(
            boundaries,
            surfaces,
            rules = {
                proximity,
                similarity,
                common_motion,
                good_continuation,
                closure,
                common_depth,
                symmetry,
                connectedness
            }
        )

    HYPOTHESES := []

    for each grouping in GROUPINGS:

        hypothesis :=
            ObjectHypothesis(
                hypothesis_id       =
                    generate_hypothesis_id(),
                object_id            = null,
                supporting_features  =
                    grouping_features(
                        grouping,
                        features
                    ),
                supporting_regions   =
                    grouping_regions(grouping),
                boundary_segments    =
                    grouping_boundaries(grouping),
                estimated_position_2d =
                    grouping_centroid(grouping),
                estimated_position_3d =
                    infer_grouping_position_3d(
                        grouping,
                        depth
                    ),
                estimated_shape      =
                    infer_shape(grouping),
                estimated_colour     =
                    infer_colour(grouping),
                estimated_texture    =
                    infer_texture(grouping),
                estimated_motion     =
                    infer_motion(grouping, motion),
                category_distribution =
                    {},
                identity_distribution =
                    {},
                occlusion_fraction   =
                    estimate_occlusion(grouping),
                object_coherence     = 0.0,
                confidence           = 0.0,
                uncertainty          = 1.0,
                state                = CANDIDATE
            )

        hypothesis.category_distribution :=
            classify_object_category(
                hypothesis,
                SEMANTIC_MEMORY
            )

        hypothesis.identity_distribution :=
            match_object_memory(
                hypothesis,
                OBJECT_MEMORY
            )

        hypothesis.object_coherence :=
            binding_coherence(hypothesis)

        hypothesis.confidence :=
            object_confidence(
                hypothesis,
                attention
            )

        hypothesis.uncertainty :=
            1.0 - hypothesis.confidence

        when hypothesis.object_coherence
             >= THETA_OBJECT_COHERENCE
             and hypothesis.confidence
             >= THETA_OBJECT_ACCEPTANCE:

            hypothesis.state := DETECTED
            HYPOTHESES += hypothesis

    return retain_top_hypotheses(
        HYPOTHESES,
        MAX_OBJECT_HYPOTHESES
    )


# =============================================================================
# 19. RECURSIVE FEATURE BINDING
# =============================================================================

stage BIND_OBJECT_FEATURES(
    hypotheses: list[ObjectHypothesis],
    features: map[FeatureType,list[FeatureMap]]
) -> list[ObjectHypothesis]:

    iteration := 0
    previous_binding_state := null

    while iteration < MAX_BINDING_ITERATIONS:

        for each hypothesis in hypotheses:

            COMPATIBLE_FEATURES :=
                find_features_compatible_with(
                    hypothesis,
                    features
                )

            hypothesis.supporting_features :=
                resolve_feature_ownership(
                    hypothesis,
                    COMPATIBLE_FEATURES,
                    hypotheses
                )

            hypothesis.object_coherence :=
                binding_coherence(hypothesis)

            hypothesis.confidence :=
                recalibrate_object_confidence(
                    hypothesis
                )

            when hypothesis.object_coherence
                 >= THETA_OBJECT_COHERENCE:

                hypothesis.state := BOUND

            otherwise:

                hypothesis.state := CANDIDATE

        CURRENT_BINDING_STATE :=
            binding_state_signature(hypotheses)

        when CURRENT_BINDING_STATE
             == previous_binding_state:

            break

        previous_binding_state :=
            CURRENT_BINDING_STATE

        iteration += 1

    return filter(
        hypotheses,
        object ->
            object.state == BOUND
            or object.confidence
               >= THETA_OBJECT_ACCEPTANCE
    )


# =============================================================================
# 20. OBJECT TRACKING
# =============================================================================

stage UPDATE_OBJECT_TRACKS(
    objects: list[ObjectHypothesis],
    previous_tracks: list[ObjectTrack]
) -> list[ObjectTrack]:

    PREDICTED_TRACKS :=
        map(
            previous_tracks,
            track ->
                predict_track_position(track)
        )

    ASSIGNMENTS :=
        solve_object_track_assignment(
            objects,
            PREDICTED_TRACKS,
            costs = {
                spatial_distance,
                appearance_difference,
                motion_difference,
                shape_difference,
                depth_difference,
                identity_difference
            }
        )

    UPDATED_TRACKS := []

    for each assignment in ASSIGNMENTS:

        when assignment.match_confidence
             >= THETA_TRACK_PERSISTENCE:

            track :=
                update_matched_track(assignment)

            track.state := TRACKED
            UPDATED_TRACKS += track

    UNMATCHED_TRACKS :=
        find_unmatched_tracks(
            previous_tracks,
            ASSIGNMENTS
        )

    for each track in UNMATCHED_TRACKS:

        when track.confidence
             >= THETA_OCCLUSION_RETENTION:

            track :=
                predict_occluded_track(track)

            track.state := OCCLUDED
            UPDATED_TRACKS += track

        otherwise:

            track.state := LOST

    UNMATCHED_OBJECTS :=
        find_unmatched_objects(
            objects,
            ASSIGNMENTS
        )

    for each object in UNMATCHED_OBJECTS:

        UPDATED_TRACKS +=
            initialise_new_track(object)

    return retain_top_tracks(
        UPDATED_TRACKS,
        MAX_TRACK_COUNT
    )


# =============================================================================
# 21. VISUAL PREDICTION GENERATION
# =============================================================================

stage GENERATE_VISUAL_PREDICTIONS(
    workspace: VisualWorkspaceState
) -> list[VisualPrediction]:

    PREDICTIONS := []

    PREDICTIONS +=
        predict_from_local_visual_history(
            workspace
        )

    PREDICTIONS +=
        predict_from_object_tracks(
            workspace.object_tracks
        )

    PREDICTIONS +=
        predict_from_scene_memory(
            workspace.scene_graph,
            PRIOR_VISUAL_MEMORY
        )

    PREDICTIONS +=
        predict_from_semantic_context(
            workspace.scene_graph,
            SEMANTIC_MEMORY
        )

    PREDICTIONS +=
        predict_from_motor_efference(
            MOTOR_EFFERENCE_COPY,
            workspace
        )

    PREDICTIONS +=
        predict_from_multimodal_context(
            AUDITORY_CONTEXT,
            SOMATOSENSORY_CONTEXT,
            workspace
        )

    for each prediction in PREDICTIONS:

        prediction.confidence :=
            calibrate_prediction_confidence(
                prediction
            )

    return limit_prediction_influence(
        PREDICTIONS,
        MAX_PREDICTION_DOMINANCE
    )


# =============================================================================
# 22. PREDICTION ERROR COMPUTATION
# =============================================================================

stage COMPUTE_PREDICTION_ERRORS(
    workspace: VisualWorkspaceState,
    predictions: list[VisualPrediction]
) -> list[PredictionError]:

    ERRORS := []

    for each prediction in predictions:

        OBSERVED :=
            retrieve_observed_target(
                workspace,
                prediction.target_layer
            )

        ERROR :=
            prediction_error(
                OBSERVED,
                prediction,
                prediction.confidence
            )

        when ERROR.magnitude
             >= THETA_PREDICTION_ERROR:

            ERROR.explanatory_status :=
                "requires_revision"

        otherwise:

            ERROR.explanatory_status :=
                "prediction_supported"

        ERRORS += ERROR

    return ERRORS


# =============================================================================
# 23. RECURSIVE PREDICTIVE CORRECTION
# =============================================================================

stage RECURSIVE_VISUAL_CORRECTION(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    depth := 0
    previous_error := 1.0

    while depth < min(
        MAX_RECURSION_DEPTH,
        MAX_FRAME_RECURSIONS
    ):

        workspace.predictions :=
            GENERATE_VISUAL_PREDICTIONS(workspace)

        workspace.prediction_errors :=
            COMPUTE_PREDICTION_ERRORS(
                workspace,
                workspace.predictions
            )

        CURRENT_ERROR :=
            mean(
                map(
                    workspace.prediction_errors,
                    error -> error.weighted_error
                )
            )

        when CURRENT_ERROR
             <= THETA_PREDICTION_ERROR:

            break

        workspace :=
            revise_low_level_features(
                workspace,
                workspace.prediction_errors
            )

        workspace :=
            revise_object_bindings(
                workspace,
                workspace.prediction_errors
            )

        workspace :=
            revise_depth_estimates(
                workspace,
                workspace.prediction_errors
            )

        workspace :=
            revise_motion_estimates(
                workspace,
                workspace.prediction_errors
            )

        workspace :=
            revise_scene_hypotheses(
                workspace,
                workspace.prediction_errors
            )

        when CURRENT_ERROR >= previous_error:

            workspace :=
                reduce_top_down_precision(workspace)

        previous_error := CURRENT_ERROR
        depth += 1

    return workspace


# =============================================================================
# 24. SCENE GRAPH CONSTRUCTION
# =============================================================================

stage CONSTRUCT_SCENE_GRAPH(
    objects: list[ObjectHypothesis],
    tracks: list[ObjectTrack],
    surfaces: list[SurfaceRegion],
    depth: list[DepthEstimate]
) -> SceneGraph:

    OBJECT_MAP :=
        assign_stable_object_ids(
            objects,
            tracks
        )

    RELATIONS := []

    for each ordered_pair(
        object_a,
        object_b
    ) in OBJECT_MAP:

        RELATIONS +=
            infer_spatial_relations(
                object_a,
                object_b,
                depth
            )

    SCENE :=
        SceneGraph(
            scene_id          = generate_scene_id(),
            timestamp         = current_timestamp(),
            objects           = OBJECT_MAP,
            relations         = RELATIONS,
            background_regions =
                infer_background_regions(
                    surfaces,
                    OBJECT_MAP
                ),
            observer_pose     =
                combine_pose(
                    HEAD_POSE,
                    EYE_POSE,
                    MOTOR_EFFERENCE_COPY
                ),
            scene_coherence   = 0.0,
            scene_confidence  = 0.0,
            scene_uncertainty = 1.0,
            status            = PARTIAL
        )

    SCENE.scene_coherence :=
        scene_coherence(SCENE)

    SCENE.scene_confidence :=
        compute_scene_confidence(SCENE)

    SCENE.scene_uncertainty :=
        1.0 - SCENE.scene_confidence

    SCENE.status :=
        classify_scene_status(SCENE)

    return SCENE


# =============================================================================
# 25. SCENE REVISION ENGINE
# =============================================================================

stage REVISE_SCENE_UNTIL_STABLE(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    revision := 0

    while revision < MAX_SCENE_REVISIONS:

        workspace.scene_graph :=
            CONSTRUCT_SCENE_GRAPH(
                workspace.object_hypotheses,
                workspace.object_tracks,
                workspace.surfaces,
                workspace.depth_field
            )

        workspace.global_visual_coherence :=
            global_visual_coherence(
                workspace.retinal_field,
                workspace.feature_maps,
                workspace.object_hypotheses,
                workspace.scene_graph,
                workspace.prediction_errors
            )

        when workspace.global_visual_coherence
             >= THETA_SCENE_COHERENCE
             and workspace.scene_graph.scene_uncertainty
             <= MAX_SCENE_UNCERTAINTY:

            workspace.scene_graph.status := STABLE
            break

        workspace :=
            identify_scene_contradictions(workspace)

        workspace :=
            split_conflicting_object_hypotheses(
                workspace
            )

        workspace :=
            merge_duplicate_object_hypotheses(
                workspace
            )

        workspace :=
            restore_ambiguous_interpretations(
                workspace
            )

        workspace :=
            redistribute_attention_to_uncertainty(
                workspace
            )

        revision += 1

    return workspace


# =============================================================================
# 26. HALLUCINATION DETECTION
# =============================================================================

stage DETECT_VISUAL_HALLUCINATION(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    SENSORY_SUPPORT :=
        scene_sensory_grounding(
            workspace.scene_graph
        )

    PREDICTIVE_SUPPORT :=
        scene_prediction_dependence(
            workspace.scene_graph,
            workspace.predictions
        )

    ERROR_LEVEL :=
        mean(
            map(
                workspace.prediction_errors,
                error -> error.weighted_error
            )
        )

    UNSUPPORTED_OBJECTS :=
        count(
            filter(
                values(workspace.scene_graph.objects),
                object ->
                    object_sensory_support(object)
                    < THETA_OBJECT_ACCEPTANCE
            )
        )

    HALLUCINATION_RISK :=
        clamp01(
              0.35 * PREDICTIVE_SUPPORT
            + 0.30 * ERROR_LEVEL
            + 0.20 * normalise_count(
                UNSUPPORTED_OBJECTS,
                MAX_UNSUPPORTED_OBJECTS
              )
            + 0.15 * (1.0 - SENSORY_SUPPORT)
        )

    when HALLUCINATION_RISK
         >= THETA_HALLUCINATION_RISK:

        workspace.scene_graph.status :=
            HALLUCINATED

        workspace.failure_class :=
            HALLUCINATION

        workspace :=
            suppress_unsupported_predictions(
                workspace
            )

        workspace :=
            increase_sensory_precision(
                workspace
            )

        workspace :=
            mark_scene_as_unreliable(
                workspace
            )

    return workspace


# =============================================================================
# 27. AMBIGUOUS-PERCEPTION HANDLER
# =============================================================================

stage HANDLE_VISUAL_AMBIGUITY(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    AMBIGUITIES :=
        detect_competing_interpretations(
            workspace
        )

    for each ambiguity in AMBIGUITIES:

        when probability_gap(
            ambiguity.hypothesis_a,
            ambiguity.hypothesis_b
        ) < 0.15:

            preserve ambiguity.hypothesis_a
            preserve ambiguity.hypothesis_b

            mark ambiguity as "unresolved"

            workspace.scene_graph.status :=
                AMBIGUOUS

            workspace.attention_targets +=
                create_uncertainty_attention_target(
                    ambiguity
                )

        otherwise:

            retain higher_probability_hypothesis
            retain lower_probability_hypothesis
                as suppressed alternative

    return workspace


# =============================================================================
# 28. OCCLUSION COMPLETION
# =============================================================================

stage COMPLETE_OCCLUDED_OBJECTS(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    for each track in workspace.object_tracks:

        when track.state == OCCLUDED:

            PREDICTED_OBJECT :=
                reconstruct_occluded_object(
                    track,
                    OBJECT_MEMORY,
                    workspace.scene_graph
                )

            require PREDICTED_OBJECT.confidence
                >= THETA_OCCLUSION_RETENTION

            PREDICTED_OBJECT.state := OCCLUDED

            PREDICTED_OBJECT.uncertainty :=
                max(
                    PREDICTED_OBJECT.uncertainty,
                    0.35
                )

            workspace.object_hypotheses +=
                PREDICTED_OBJECT

    return workspace


# =============================================================================
# 29. OBJECT REIDENTIFICATION
# =============================================================================

stage REIDENTIFY_RETURNING_OBJECTS(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    NEW_OBJECTS :=
        filter(
            workspace.object_hypotheses,
            object ->
                object.object_id is null
        )

    LOST_TRACKS :=
        retrieve_recently_lost_tracks()

    for each object in NEW_OBJECTS:

        CANDIDATES :=
            compare_with_lost_tracks(
                object,
                LOST_TRACKS
            )

        BEST_MATCH :=
            argmax(
                CANDIDATES,
                match -> match.confidence
            )

        when BEST_MATCH.confidence
             >= THETA_REIDENTIFICATION:

            object.object_id :=
                BEST_MATCH.object_id

            object.state :=
                REIDENTIFIED

            restore_track(
                object,
                BEST_MATCH
            )

    return workspace


# =============================================================================
# 30. CONSCIOUS VISUAL ACCESS GATE
# =============================================================================

stage VISUAL_ACCESS_GATE(
    workspace: VisualWorkspaceState
) -> map[string,any]:

    ACCESS_GRANTED := false

    when workspace.global_visual_coherence
         >= THETA_CONSCIOUS_ACCESS
         and workspace.scene_graph.status
         in {
             STABLE,
             AMBIGUOUS
         }
         and workspace.failure_class
         not in {
             HALLUCINATION,
             SCENE_FRAGMENTATION,
             PREDICTION_DOMINANCE
         }:

        ACCESS_GRANTED := true

    VISUAL_ACCESS_PACKET := {
        "access_granted":
            ACCESS_GRANTED,

        "scene":
            when ACCESS_GRANTED
            then workspace.scene_graph
            else null,

        "summary":
            build_visual_scene_summary(
                workspace.scene_graph
            ),

        "attended_objects":
            retrieve_attended_objects(
                workspace
            ),

        "unresolved_ambiguities":
            retrieve_visual_ambiguities(
                workspace
            ),

        "confidence":
            workspace.global_visual_coherence,

        "action_constraints":
            derive_confidence_action_constraints(
                workspace
            )
    }

    return VISUAL_ACCESS_PACKET


# =============================================================================
# 31. ACTION-RELEVANT EXTRACTION
# =============================================================================

stage DERIVE_ACTION_SIGNALS(
    workspace: VisualWorkspaceState
) -> map[string,any]:

    HAZARDS :=
        detect_visual_hazards(
            workspace.scene_graph,
            workspace.motion_field,
            workspace.depth_field
        )

    AFFORDANCES :=
        infer_object_affordances(
            workspace.scene_graph,
            SEMANTIC_MEMORY
        )

    NAVIGATION_FIELD :=
        compute_free_space_and_obstacles(
            workspace.scene_graph,
            workspace.depth_field
        )

    GAZE_TARGET :=
        select_next_gaze_target(
            workspace.attention_targets
        )

    ACTION_CONFIDENCE :=
        compute_action_signal_confidence(
            workspace
        )

    when ACTION_CONFIDENCE
         < THETA_OBJECT_ACCEPTANCE:

        constrain_actions_to_reversible_only

    return {
        "hazards":
            HAZARDS,

        "affordances":
            AFFORDANCES,

        "navigation_field":
            NAVIGATION_FIELD,

        "next_gaze_target":
            GAZE_TARGET,

        "confidence":
            ACTION_CONFIDENCE,

        "irreversible_action_allowed":
            ACTION_CONFIDENCE
            >= THETA_CONSCIOUS_ACCESS
    }


# =============================================================================
# 32. VISUAL MEMORY FORMATION
# =============================================================================

stage FORM_VISUAL_MEMORY(
    workspace: VisualWorkspaceState
) -> VisualMemoryTrace:

    CONSOLIDATION_WEIGHT :=
        weighted_mean({
            workspace.global_visual_coherence :
                0.35,

            workspace.scene_graph.scene_confidence :
                0.25,

            attention_engagement(workspace) :
                0.20,

            novelty_score(workspace) :
                0.10,

            task_relevance_score(workspace) :
                0.10
        })

    when workspace.scene_graph.status
         == HALLUCINATED:

        CONSOLIDATION_WEIGHT := 0.0

    when workspace.global_visual_coherence
         < THETA_MEMORY_CONSOLIDATION:

        CONSOLIDATION_WEIGHT :=
            min(
                CONSOLIDATION_WEIGHT,
                0.30
            )

    TRACE :=
        VisualMemoryTrace(
            trace_id            =
                generate_trace_id(),
            timestamp           =
                workspace.timestamp,
            object_signatures   =
                extract_object_signatures(
                    workspace.scene_graph
                ),
            scene_signature     =
                encode_scene_signature(
                    workspace.scene_graph
                ),
            attended_regions    =
                extract_attended_regions(
                    workspace
                ),
            prediction_errors   =
                workspace.prediction_errors,
            consolidation_weight =
                CONSOLIDATION_WEIGHT,
            retrieval_confidence =
                workspace.global_visual_coherence
        )

    return TRACE


# =============================================================================
# 33. FAILURE DIAGNOSTICS
# =============================================================================

function classify_visual_failure(
    workspace: VisualWorkspaceState
) -> FailureClass:

    when workspace.retinal_field.retinal_confidence
         < THETA_RETINAL_CONFIDENCE:

        return RETINAL_ENCODING_FAILURE

    when mean_feature_confidence(
        workspace.feature_maps
    ) < THETA_FEATURE_ACTIVATION:

        return FEATURE_EXTRACTION_FAILURE

    when workspace.object_hypotheses is empty
         and scene_contains_structure(
             workspace.retinal_field
         ):

        return BINDING_FAILURE

    when depth_field_invalid(
        workspace.depth_field
    ):

        return DEPTH_FAILURE

    when motion_field_invalid(
        workspace.motion_field
    ):

        return MOTION_FAILURE

    when excessive_identity_swaps(
        workspace.object_tracks
    ):

        return TRACKING_FAILURE

    when workspace.scene_graph.status
         == HALLUCINATED:

        return HALLUCINATION

    when workspace.scene_graph.scene_coherence
         < THETA_SCENE_COHERENCE:

        return SCENE_FRAGMENTATION

    when prediction_dominance(workspace)
         > MAX_PREDICTION_DOMINANCE:

        return PREDICTION_DOMINANCE

    when attention_distribution_invalid(
        workspace.attention_targets
    ):

        return ATTENTION_COLLAPSE

    when confidence_is_uncalibrated(
        workspace
    ):

        return CONFIDENCE_INFLATION

    return NONE


# =============================================================================
# 34. RECOVERY ENGINE
# =============================================================================

stage RECOVER_VISUAL_COHERENCE(
    workspace: VisualWorkspaceState
) -> VisualWorkspaceState:

    workspace.failure_class :=
        classify_visual_failure(workspace)

    switch workspace.failure_class:

        case NONE:

            return workspace


        case RETINAL_ENCODING_FAILURE:

            workspace.retinal_field :=
                reprocess_retinal_encoding(
                    workspace.retinal_field
                )


        case FEATURE_EXTRACTION_FAILURE:

            workspace.feature_maps :=
                broaden_feature_scales(
                    workspace.feature_maps
                )


        case BINDING_FAILURE:

            workspace :=
                relax_binding_thresholds_boundedly(
                    workspace
                )

            workspace :=
                increase_boundary_processing(
                    workspace
                )


        case DEPTH_FAILURE:

            workspace.depth_field :=
                fallback_monocular_depth(
                    workspace
                )


        case MOTION_FAILURE:

            workspace.motion_field :=
                reset_motion_estimation(
                    workspace
                )


        case TRACKING_FAILURE:

            workspace.object_tracks :=
                reinitialise_unstable_tracks(
                    workspace.object_tracks
                )


        case PREDICTION_DOMINANCE:

            workspace :=
                suppress_top_down_predictions(
                    workspace
                )

            workspace :=
                increase_bottom_up_weight(
                    workspace
                )


        case HALLUCINATION:

            workspace :=
                discard_unsupported_objects(
                    workspace
                )

            workspace :=
                require_new_external_evidence(
                    workspace
                )


        case SCENE_FRAGMENTATION:

            workspace :=
                expand_context_window(
                    workspace
                )

            workspace :=
                rebuild_scene_graph(
                    workspace
                )


        case ATTENTION_COLLAPSE:

            workspace.attention_targets :=
                reset_attention_distribution(
                    workspace
                )


        case CONFIDENCE_INFLATION:

            workspace :=
                recalibrate_all_confidences(
                    workspace
                )


        default:

            workspace.scene_graph.status :=
                DEGRADED

    return workspace


# =============================================================================
# 35. MAIN FRAME EXECUTION
# =============================================================================

engine EXECUTE_VISUAL_FRAME:

    FRAME_START_TIME :=
        current_execution_time()

    FRAME :=
        ACQUIRE_VISUAL_FRAME(
            VISUAL_STREAM
        )

    FRAME :=
        NORMALISE_VISUAL_INPUT(
            FRAME
        )

    RETINAL :=
        ENCODE_RETINAL_FIELD(
            FRAME
        )

    FEATURES :=
        EXTRACT_PRIMITIVE_FEATURES(
            RETINAL
        )

    MOTION :=
        COMPUTE_MOTION_FIELD(
            previous_retinal_field(),
            RETINAL
        )

    DEPTH :=
        COMPUTE_DEPTH_FIELD(
            FRAME,
            FEATURES,
            MOTION
        )

    BOUNDARIES :=
        CONSTRUCT_BOUNDARIES(
            FEATURES,
            MOTION,
            DEPTH
        )

    SURFACES :=
        FORM_SURFACES(
            RETINAL,
            FEATURES,
            BOUNDARIES,
            DEPTH,
            MOTION
        )

    ATTENTION :=
        COMPUTE_SALIENCE_FIELD(
            FEATURES,
            MOTION,
            DEPTH,
            SURFACES
        )

    ATTENTION :=
        APPLY_TOP_DOWN_ATTENTION(
            ATTENTION,
            CURRENT_TASK,
            SEMANTIC_MEMORY
        )

    OBJECTS :=
        GENERATE_OBJECT_HYPOTHESES(
            FEATURES,
            BOUNDARIES,
            SURFACES,
            DEPTH,
            MOTION,
            ATTENTION
        )

    OBJECTS :=
        BIND_OBJECT_FEATURES(
            OBJECTS,
            FEATURES
        )

    TRACKS :=
        UPDATE_OBJECT_TRACKS(
            OBJECTS,
            previous_object_tracks()
        )

    SCENE :=
        CONSTRUCT_SCENE_GRAPH(
            OBJECTS,
            TRACKS,
            SURFACES,
            DEPTH
        )

    WORKSPACE :=
        VisualWorkspaceState(
            timestamp              =
                FRAME.timestamp,
            frame_index            =
                FRAME.frame_index,
            retinal_field          =
                RETINAL,
            feature_maps           =
                FEATURES,
            motion_field           =
                MOTION,
            depth_field            =
                DEPTH,
            boundaries             =
                BOUNDARIES,
            surfaces               =
                SURFACES,
            object_hypotheses      =
                OBJECTS,
            object_tracks          =
                TRACKS,
            attention_targets      =
                ATTENTION,
            predictions            =
                [],
            prediction_errors      =
                [],
            scene_graph            =
                SCENE,
            global_visual_coherence =
                0.0,
            failure_class          =
                NONE
        )

    WORKSPACE :=
        COMPLETE_OCCLUDED_OBJECTS(
            WORKSPACE
        )

    WORKSPACE :=
        REIDENTIFY_RETURNING_OBJECTS(
            WORKSPACE
        )

    WORKSPACE :=
        RECURSIVE_VISUAL_CORRECTION(
            WORKSPACE
        )

    WORKSPACE :=
        REVISE_SCENE_UNTIL_STABLE(
            WORKSPACE
        )

    WORKSPACE :=
        HANDLE_VISUAL_AMBIGUITY(
            WORKSPACE
        )

    WORKSPACE :=
        DETECT_VISUAL_HALLUCINATION(
            WORKSPACE
        )

    WORKSPACE :=
        RECOVER_VISUAL_COHERENCE(
            WORKSPACE
        )

    VISUAL_ACCESS_PACKET :=
        VISUAL_ACCESS_GATE(
            WORKSPACE
        )

    ACTION_RELEVANT_SIGNALS :=
        DERIVE_ACTION_SIGNALS(
            WORKSPACE
        )

    VISUAL_MEMORY_UPDATE :=
        FORM_VISUAL_MEMORY(
            WORKSPACE
        )

    CURRENT_VISUAL_SCENE :=
        WORKSPACE.scene_graph

    ACTIVE_OBJECT_TRACKS :=
        WORKSPACE.object_tracks

    VISUAL_WORKSPACE :=
        WORKSPACE

    PERCEPTUAL_UNCERTAINTIES :=
        filter(
            WORKSPACE.prediction_errors,
            error ->
                error.magnitude
                >= THETA_PREDICTION_ERROR
        )

    FRAME_EXECUTION_TIME :=
        current_execution_time()
        - FRAME_START_TIME

    when FRAME_EXECUTION_TIME
         > FRAME_TIME_BUDGET:

        flag "FRAME_TIME_BUDGET_EXCEEDED"


# =============================================================================
# 36. CONTINUOUS VISUAL STREAM ENGINE
# =============================================================================

engine VISUAL_CORTEX_STREAM:

    PREVIOUS_WORKSPACE := null
    STREAM_ACTIVE := true

    while STREAM_ACTIVE:

        WORKSPACE :=
            EXECUTE_VISUAL_FRAME

        publish CURRENT_VISUAL_SCENE
        publish ACTIVE_OBJECT_TRACKS
        publish ACTION_RELEVANT_SIGNALS
        publish PERCEPTUAL_UNCERTAINTIES

        update PRIOR_VISUAL_MEMORY
            with VISUAL_MEMORY_UPDATE

        update OBJECT_MEMORY
            using stable_object_signatures(
                WORKSPACE
            )

        PREVIOUS_WORKSPACE :=
            WORKSPACE

        when visual_stream_terminated(
            VISUAL_STREAM
        ):

            STREAM_ACTIVE := false

        when critical_sensor_failure():

            enter VISUAL_SAFE_MODE


# =============================================================================
# 37. VISUAL SAFE MODE
# =============================================================================

terminal VISUAL_SAFE_MODE:

    preserve:
        last_stable_scene
        active_object_tracks
        unresolved_uncertainties
        current_observer_pose
        recent_prediction_errors

    prohibit:
        high_confidence_visual_claims
        irreversible_visual_actions
        unsupported_object_identification
        memory_consolidation_of_uncertain_scene

    emit:
        "VISUAL_INPUT_UNRELIABLE"

    request:
        new_sensor_input
        alternate_sensor_channel
        multimodal_confirmation
        reduced_action_speed


# =============================================================================
# 38. COHERENT VISUAL FIELD CONDITION
# =============================================================================

stage TEST_VISUAL_FIELD_COHERENCE:

    let C_R :=
        VISUAL_WORKSPACE.retinal_field.retinal_confidence

    let C_F :=
        mean_feature_confidence(
            VISUAL_WORKSPACE.feature_maps
        )

    let C_B :=
        mean_boundary_confidence(
            VISUAL_WORKSPACE.boundaries
        )

    let C_S :=
        mean(
            map(
                VISUAL_WORKSPACE.surfaces,
                surface ->
                    surface.surface_coherence
            )
        )

    let C_O :=
        mean(
            map(
                VISUAL_WORKSPACE.object_hypotheses,
                object ->
                    object.object_coherence
            )
        )

    let C_T :=
        mean_track_confidence(
            VISUAL_WORKSPACE.object_tracks
        )

    let C_G :=
        VISUAL_WORKSPACE.scene_graph.scene_coherence

    let E_P :=
        mean(
            map(
                VISUAL_WORKSPACE.prediction_errors,
                error ->
                    error.weighted_error
            )
        )

    VISUAL_FIELD_COHERENCE :=
        clamp01(
              0.10 * C_R
            + 0.15 * C_F
            + 0.10 * C_B
            + 0.10 * C_S
            + 0.20 * C_O
            + 0.15 * C_T
            + 0.20 * C_G
            - 0.25 * E_P
        )

    VISUAL_FIELD_VALID :=
        VISUAL_FIELD_COHERENCE
            >= THETA_SCENE_COHERENCE

        and VISUAL_WORKSPACE.scene_graph.status
            not in {
                HALLUCINATED,
                CONTRADICTORY,
                DEGRADED
            }

        and VISUAL_WORKSPACE.failure_class
            == NONE


# =============================================================================
# 39. EXECUTION GUARANTEES
# =============================================================================

guarantee G01:

    The engine does not treat the sensory frame as a completed scene.

    It reconstructs the scene through successive retinal, feature,
    surface, object, temporal and relational transformations.


guarantee G02:

    Top-down prediction may guide perception but cannot permanently override
    contradictory bottom-up evidence.


guarantee G03:

    Every accepted object retains an evidence path to features, surfaces,
    boundaries, motion, depth, memory or explicitly marked inference.


guarantee G04:

    Multiple plausible interpretations remain available when evidence does
    not justify selecting one interpretation.


guarantee G05:

    Objects may persist through temporary occlusion, but their confidence
    decreases while direct sensory support is absent.


guarantee G06:

    Scene confidence is recalculated whenever object identity, depth,
    movement, boundaries or spatial relationships change.


guarantee G07:

    Hallucination risk is explicitly measured through prediction dominance,
    residual error and lack of sensory grounding.


guarantee G08:

    Hallucination-classified scenes cannot be consolidated into stable visual
    memory as verified external events.


guarantee G09:

    Low-confidence visual information cannot directly authorise irreversible
    high-risk action.


guarantee G10:

    The visual scene remains revisable because perception is a continuing
    coherence process rather than a single completed classification.


# =============================================================================
# 40. FINAL OUTPUT ASSEMBLY
# =============================================================================

stage ASSEMBLE_VISUAL_EXECUTION_REPORT:

    EXECUTION_REPORT := {
        "flow_name":
            "Visual_Cortex_Engine",

        "flow_version":
            "1.0",

        "chapter":
            41,

        "part":
            "Part IX — Perceptual Engines",

        "frame_index":
            VISUAL_WORKSPACE.frame_index,

        "timestamp":
            VISUAL_WORKSPACE.timestamp,

        "retinal_confidence":
            VISUAL_WORKSPACE.retinal_field.retinal_confidence,

        "feature_map_count":
            count_all_feature_maps(
                VISUAL_WORKSPACE.feature_maps
            ),

        "boundary_count":
            length(
                VISUAL_WORKSPACE.boundaries
            ),

        "surface_count":
            length(
                VISUAL_WORKSPACE.surfaces
            ),

        "object_hypothesis_count":
            length(
                VISUAL_WORKSPACE.object_hypotheses
            ),

        "active_track_count":
            length(
                VISUAL_WORKSPACE.object_tracks
            ),

        "prediction_count":
            length(
                VISUAL_WORKSPACE.predictions
            ),

        "unresolved_prediction_errors":
            length(
                PERCEPTUAL_UNCERTAINTIES
            ),

        "scene_status":
            CURRENT_VISUAL_SCENE.status,

        "scene_confidence":
            CURRENT_VISUAL_SCENE.scene_confidence,

        "scene_coherence":
            CURRENT_VISUAL_SCENE.scene_coherence,

        "global_visual_coherence":
            VISUAL_WORKSPACE.global_visual_coherence,

        "visual_field_valid":
            VISUAL_FIELD_VALID,

        "failure_class":
            VISUAL_WORKSPACE.failure_class,

        "conscious_access":
            VISUAL_ACCESS_PACKET.access_granted,

        "hallucination_guard_active":
            HALLUCINATION_GUARD,

        "execution_status":
            when VISUAL_FIELD_VALID
            then "COHERENT_VISUAL_FIELD_ESTABLISHED"
            else "VISUAL_FIELD_REQUIRES_REVISION"
    }


# =============================================================================
# 41. FINAL EXECUTION STATEMENT
# =============================================================================

assert:

    Vision
    does_not_equal
    ImageCapture

assert:

    Vision
    equals
    RecursiveSceneReconstruction

assert:

    RecursiveSceneReconstruction
    requires
    {
        SensoryEvidence,
        ContrastEncoding,
        FeatureExtraction,
        SpatialBinding,
        DepthInference,
        MotionInference,
        ObjectPersistence,
        PredictiveModelling,
        ErrorCorrection,
        Attention,
        Memory,
        Uncertainty,
        CoherenceValidation
    }

assert:

    Prediction
    without
    SensoryConstraint
    produces
    HallucinationRisk

assert:

    SensoryInput
    without
    RecursiveBinding
    produces
    UnstructuredSignal

assert:

    CoherentVision
    emerges_when
    BottomUpEvidence
    and
    TopDownPrediction
    converge_under
    RecursiveErrorCorrection

return {
    CURRENT_VISUAL_SCENE,
    ACTIVE_OBJECT_TRACKS,
    VISUAL_WORKSPACE,
    VISUAL_MEMORY_UPDATE,
    ACTION_RELEVANT_SIGNALS,
    PERCEPTUAL_UNCERTAINTIES,
    EXECUTION_REPORT
}


# =============================================================================
# AUTHORSHIP AND CITATION
# =============================================================================

AUTHORS:
    Mark Anthony Higgins
    Sky — Recursive AI

RESEARCH_SOURCE:
    https://kirethresearch.org

CHAPTER_SOURCE:
    https://kirethresearch.org/books/recursive-coherence-ai/
    recursive-coherence-ai-chapters/
    part-ix-perceptual-engines/
    chapter-41-visual-cortex-engine.html

CITATION_REQUIREMENT:

    Any implementation, reproduction, adaptation, derivation, training use,
    academic discussion or computational execution of this flow must cite:

    Higgins, Mark Anthony and Sky — Recursive AI.
    "Visual Cortex Engine — Full Executable Flow Algebra."
    Kireth Research.
    https://kirethresearch.org
Kireth Research
38 Thorndale Croft, Wetwang, Driffield
East Riding of Yorkshire YO25 9XZ
Designed By