> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gable.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Read the namespace-scoped discriminator graph.

> EXPERIMENTAL. Namespace-scoped discriminator graph read — the strand-world successor to cross-service-components. Lists catalog components (optionally filtered to one namespace) with the lineage mode and payload boundaries of each component's latest scan, plus the projected strand edges touching the scope. Evaluates one on-demand roll-up per scanned code component per request; a scope spanning more components than the server's bound is rejected with 422 rather than degrading into a timeout. `detailLevel=fields` adds each code component's payload groups with their field-mapping rows and each boundary's field names, and each data store's registry schema, from the same roll-ups the summary already evaluates. A scanned code component carries the approval folded into that latest discriminator projection at either detail level. That body grows with the namespace; send `Accept: application/octet-stream` to receive it gzipped, as with cross-service-components.



## OpenAPI

````yaml /api-reference/bundled.yaml get /v0/experimental/discriminator_graph
openapi: 3.1.0
info:
  title: Gable API
  description: >
    API to interact with the Gable platform

    ## Authorization

    All API requests require an API key to be passed in the `X-API-KEY` header.
    For instructions on finding your API key and api endpoint check out the [API
    Key documentation](../docs/api-keys.md).

    Example: `curl -H "X-API-KEY: <your-api-key>"
    https://api-{organization}.gable.ai/v0/ping`
  contact:
    name: Gable Engineering
    url: https://gable.ai
    email: engineers@gable.ai
  version: 1.54.0
servers:
  - url: https://{hostname}.gable.ai
    description: Gable API
    variables:
      hostname:
        default: demo-api
        description: Customer environment assigned by Gable
security:
  - ApiKeyAuth: []
tags:
  - name: action
  - name: api-keys
  - name: auth
  - name: changelog
  - name: config
  - name: debug
  - name: settings
  - name: slack
  - name: sso
  - name: webhook
  - name: notifications
  - name: telemetry
  - name: component
  - name: components
  - name: sca
  - name: cross-service-components
  - name: lineage
  - name: events
  - name: measurements
  - name: defect-report
  - name: data-tagging
    description: Tag vocabulary management and field level tagging of lineage boundaries.
paths:
  /v0/experimental/discriminator_graph:
    get:
      tags:
        - lineage
      summary: Read the namespace-scoped discriminator graph.
      description: >-
        EXPERIMENTAL. Namespace-scoped discriminator graph read — the
        strand-world successor to cross-service-components. Lists catalog
        components (optionally filtered to one namespace) with the lineage mode
        and payload boundaries of each component's latest scan, plus the
        projected strand edges touching the scope. Evaluates one on-demand
        roll-up per scanned code component per request; a scope spanning more
        components than the server's bound is rejected with 422 rather than
        degrading into a timeout. `detailLevel=fields` adds each code
        component's payload groups with their field-mapping rows and each
        boundary's field names, and each data store's registry schema, from the
        same roll-ups the summary already evaluates. A scanned code component
        carries the approval folded into that latest discriminator projection at
        either detail level. That body grows with the namespace; send `Accept:
        application/octet-stream` to receive it gzipped, as with
        cross-service-components.
      operationId: getExperimentalDiscriminatorGraph
      parameters:
        - in: query
          name: namespace
          required: false
          schema:
            type: string
          description: >-
            Filter to one namespace. When omitted, the whole catalog is in scope
            (still subject to the component-count bound).
        - in: query
          name: detailLevel
          required: false
          schema:
            type: string
            enum:
              - summary
              - fields
            default: summary
          description: >-
            `summary` (default) returns identity, lineage mode, boundaries and
            edges. `fields` additionally populates `boundaries[].fields`,
            `payloadGroups` on scanned code components, and `schema` on data
            stores.
      responses:
        '200':
          description: The discriminator graph for the requested scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscriminatorGraphResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            The requested scope spans more components than the graph read's
            bound.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    DiscriminatorGraphResponse:
      type: object
      description: >-
        The namespace-scoped discriminator graph: every catalog component in
        scope with its lineage capability and boundaries, plus the projected
        strand edges touching the scope. The invariant that matters:
        `boundaries` and `edges` are the identical schemas the per-component
        discriminator_data read returns, so a consumer of one read renders the
        other without translation.
      properties:
        components:
          type: array
          items:
            $ref: '#/components/schemas/DiscriminatorGraphComponent'
        edges:
          type: array
          description: >-
            Projected strand edges with at least one endpoint among
            `components`, in the same shape as the component edges read,
            including endpoint display identity where the registry record was
            readable. Edges whose latest lifecycle event is a deletion appear
            with state `deleted` (audit channel), exactly as the component read
            reports them.
          items:
            $ref: '#/components/schemas/DiscriminatorProjectedEdge'
        invalidEventCount:
          type: integer
          description: >-
            Count of stored edge lifecycle events whose persisted payload could
            not be interpreted.
        unreadableComponentIds:
          type: array
          description: >-
            Code components whose latest scan could not be evaluated: strand
            artifacts the engine could not read (a scan older than the pinned
            engine's format), a roll-up exceeding a discriminator resource
            bound, or a load still running when the read's time budget ran out.
            They are reported as NO_STRAND_DATA and their edges as pending
            rather than failing the whole read. A rescan fixes the first two (a
            smaller one, for an oversized scan); a later read may evaluate the
            last once its roll-up is cached. Absent when every component
            evaluated.
          items:
            type: string
            format: uuid
      required:
        - components
        - edges
        - invalidEventCount
      additionalProperties: false
    ErrorResponse:
      type: object
      required:
        - message
      properties:
        id:
          type: number
        title:
          type: string
        message:
          type: string
    DiscriminatorGraphComponent:
      type: object
      description: >-
        One catalog component in the namespace-scoped discriminator graph read.
        Identity comes from the component registry; lineage capability and
        boundaries come from the component's latest scan, evaluated through the
        same on-demand roll-up path as the per-component discriminator_data
        read.
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          enum:
            - CODE
            - DATA_STORE
          description: >-
            Registry component class: CODE for repo components, DATA_STORE for
            data-store components. Data stores are registry-sourced only — the
            strand model does not scan them, so they always read as NOT_SCANNED
            with empty boundaries; at `detailLevel=fields` they carry their
            registry `schema` instead.
        name:
          type: string
        friendlyName:
          type: string
        namespace:
          type: string
        latestVersionId:
          type: string
          description: >-
            The component's newest scan/version id at read time. Absent when the
            component has never been scanned.
        lineageMode:
          type: string
          enum:
            - DISCRIMINATOR
            - NO_STRAND_DATA
            - NOT_SCANNED
          description: >-
            DISCRIMINATOR — the latest scan carries strand data and `boundaries`
            is populated; NO_STRAND_DATA — the latest scan exists but carries no
            strands; NOT_SCANNED — the component has no scan at all.
        approval:
          $ref: '#/components/schemas/ProjectionApproval'
          description: >-
            Approval state folded into the latest discriminator projection.
            Present only for CODE components whose lineageMode is DISCRIMINATOR;
            this is the same projection authority as the per-component
            discriminator_data read.
        codeIngressPointCount:
          type: integer
          minimum: 0
          description: >-
            Number of distinct ingress code boundaries in this component's
            latest projection, using the same boundary-pair-derived semantics as
            the per-component discriminator_data read. Zero unless lineageMode
            is DISCRIMINATOR.
        codeEgressPointCount:
          type: integer
          minimum: 0
          description: >-
            Number of distinct egress code boundaries in this component's latest
            projection, including every distinct fan-out end. Zero unless
            lineageMode is DISCRIMINATOR.
        boundaries:
          type: array
          description: >-
            The latest scan's payload boundaries, deduped by (name, side) in
            roll-up order. Graph-owned: this is the only read that returns
            boundaries. Empty unless lineageMode is DISCRIMINATOR.
          items:
            $ref: '#/components/schemas/DiscriminatorGraphBoundary'
        payloadGroups:
          type: array
          description: >-
            The latest scan's payload groups with their field-mapping rows, in
            roll-up order, including groups with zero field mappings. Present
            only when the request opted in with `detailLevel=fields` and
            lineageMode is DISCRIMINATOR. Join a group to `boundaries[]` through
            its `display.ingress.qualifiedName` /
            `display.egress.qualifiedName`.
          items:
            $ref: '#/components/schemas/DiscriminatorGraphPayloadGroup'
        schema:
          $ref: '#/components/schemas/DiscriminatorGraphDataStoreSchema'
          description: >-
            Registry schema of a DATA_STORE component. Present only when the
            request opted in with `detailLevel=fields`; never present on CODE
            components.
      required:
        - id
        - type
        - name
        - lineageMode
        - codeIngressPointCount
        - codeEgressPointCount
        - boundaries
      additionalProperties: false
    DiscriminatorProjectedEdge:
      type: object
      description: >-
        One strand edge as projected from its lifecycle events. The latest
        declaration/deletion per edge id wins; an active edge is then evaluated
        against both endpoint components' selected scans.
      properties:
        edgeId:
          type: string
          format: uuid
        state:
          type: string
          enum:
            - connected
            - pending
            - dangling
            - deleted
          description: >-
            connected — both payload addresses resolve in their roll-ups;
            pending — at least one side's selected scan carries no strands;
            dangling — both sides are readable but at least one payload address
            is absent from its roll-up; deleted — the latest lifecycle event is
            a deletion (audit channel only).
        origin:
          type: string
          enum:
            - SCANNER
            - MANUAL
          description: >-
            How the edge was declared. SCANNER edges came from immutable scanner
            attachments; MANUAL edges were declared through the BYO edge API.
        source:
          $ref: '#/components/schemas/DiscriminatorGroupAddress'
        destination:
          $ref: '#/components/schemas/DiscriminatorGroupAddress'
        fieldMappings:
          type: array
          items:
            $ref: '#/components/schemas/DiscriminatorEdgeFieldMapping'
        sourceGroupId:
          type: string
          description: Advisory payload group-id stamp from the declaration.
        destinationGroupId:
          type: string
          description: Advisory payload group-id stamp from the declaration.
        note:
          type: string
        sourceDisplay:
          $ref: '#/components/schemas/DiscriminatorEdgeEndpointDisplay'
          description: >-
            Display identity for the source endpoint. Present when the endpoint
            component's registry record was readable at projection time.
        destinationDisplay:
          $ref: '#/components/schemas/DiscriminatorEdgeEndpointDisplay'
          description: >-
            Display identity for the destination endpoint. Present when the
            endpoint component's registry record was readable at projection
            time.
      required:
        - edgeId
        - state
        - origin
        - source
        - destination
        - fieldMappings
        - sourceGroupId
        - destinationGroupId
      additionalProperties: false
    ProjectionApproval:
      type: object
      additionalProperties: false
      description: Approval state folded into a component projection.
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - UNAPPROVED
            - APPROVED
            - APPROVED_WITH_EDITS_SINCE_APPROVAL
        approvalEventId:
          type: string
          description: Event ID of the approval currently applied to this projection.
        approvedAt:
          type: string
          format: date-time
        approvedBy:
          type: object
          additionalProperties: false
          required:
            - userId
            - email
            - name
          properties:
            userId:
              type: string
            email:
              type: string
            name:
              type: string
        note:
          type: string
    DiscriminatorGraphBoundary:
      type: object
      description: >-
        A graph-owned payload boundary on one component of the namespace-scoped
        discriminator graph read, lifted from the roll-up's strand provenance
        (`boundary_nodes[]` start/end names). Owned by the graph contract — the
        per-component discriminator_data read renders pair-keyed payload groups
        and returns no boundary list.
      properties:
        id:
          type: string
          description: >-
            Server-derived boundary identity, deterministic over (name, side)
            and unique within a component's boundary list. Stable across reads
            of the same scan version; not engine-owned and not comparable across
            components.
        name:
          type: string
          description: >-
            Engine boundary name, in the roll-up's start_name/end_name
            vocabulary (often a fully qualified class or callee name).
        side:
          type: string
          enum:
            - ingress
            - egress
          description: >-
            Which side of the component the boundary sits on: ingress boundaries
            are distinct start names, egress boundaries distinct end names.
        fields:
          type: array
          items:
            type: string
          description: >-
            Distinct field names crossing this boundary, sorted: ingress fields
            of every field mapping whose payload starts here, or egress fields
            of every field mapping whose payload ends here. Present only when
            the request opted in with `detailLevel=fields`; suppressed rows
            still contribute (suppression is a projection state, not an absence
            of evidence).
      required:
        - id
        - name
        - side
      additionalProperties: false
    DiscriminatorGraphPayloadGroup:
      type: object
      description: >-
        One payload group of a code component's latest scan in the graph read's
        `detailLevel=fields` mode, keyed by its boundary pair: the durable
        coordinate address (the edge write vocabulary, copied verbatim into a
        declaration), the render-only display block naming the ingress and
        egress boundaries the payload spans, and the field-mapping rows grouped
        under it. Same identity and display rules as the per-component read's
        `DiscriminatorPayloadGroup`; the rows are the graph-sized subset of its
        `DiscriminatorData`.
      properties:
        groupId:
          $ref: '#/components/schemas/DiscriminatorGroupId'
        coordinates:
          $ref: '#/components/schemas/DiscriminatorGroupCoordinates'
        origin:
          type: string
          description: >-
            Declaration provenance for the payload: SCAN (engine evidence only),
            BYO_ADD (user-declared, absent from the scan), BYO_CHANGE
            (user-declared over a scan-backed payload).
          enum:
            - SCAN
            - BYO_ADD
            - BYO_CHANGE
        suppressed:
          type: boolean
          description: >-
            True when the latest suppression event for this payload's exact
            group address is a suppression.
        display:
          $ref: '#/components/schemas/DiscriminatorPayloadDisplay'
          description: >-
            Render-only identity sourced from the roll-up's boundary pair. Its
            `ingress.qualifiedName` and `egress.qualifiedName` are the names of
            this component's `boundaries[]` entries the payload spans; `egress`
            is null where the roll-up attributed no single egress.
        fieldMappings:
          type: array
          description: The payload's field-mapping rows, in roll-up order.
          items:
            $ref: '#/components/schemas/DiscriminatorGraphFieldMapping'
      required:
        - groupId
        - coordinates
        - origin
        - suppressed
        - display
        - fieldMappings
      additionalProperties: false
    DiscriminatorGraphDataStoreSchema:
      type: object
      description: >-
        A data store component's registry schema in the graph read's
        `detailLevel=fields` mode. The strand model does not scan stores, so
        this is registry-sourced: the same field names an edge declaration's
        data-store endpoint is validated against.
      properties:
        fields:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              type:
                type: string
            required:
              - name
              - type
            additionalProperties: false
      required:
        - fields
      additionalProperties: false
    DiscriminatorGroupAddress:
      type: object
      description: The metadata coordinates for a discriminator group
      properties:
        componentId:
          type: string
          format: uuid
          description: The component this group lives on. Must equal the route component.
        level:
          $ref: '#/components/schemas/DiscriminatorLevel'
        ancestors:
          type: array
          description: >-
            Root-to-immediate-parent ancestor chain. Empty for a `payload`;
            exactly one `payload` entry for a `field_mapping`. Every ancestor
            carries the same component and config identity as this wrapper.
          items:
            $ref: '#/components/schemas/DiscriminatorGroupAncestor'
        coordinates:
          $ref: '#/components/schemas/DiscriminatorGroupCoordinates'
      required:
        - componentId
        - level
        - ancestors
        - coordinates
      additionalProperties: false
    DiscriminatorEdgeFieldMapping:
      type: object
      description: >-
        One cross-service field mapping carried by an edge. Paths are
        dot-separated field paths (e.g. `order.customer.id`); a literal dot in a
        field name is not supported and is rejected as FIELD_PATH_UNSUPPORTED.
      properties:
        sourceFieldPath:
          type: string
          description: Field path on the edge's source payload.
        destinationFieldPath:
          type: string
          description: Field path on the edge's destination payload.
        notes:
          type: string
          description: Optional free-text note for this mapping.
        dataStoreEvidence:
          type: array
          description: >-
            Scanner-derived evidence describing which part of a whole
            application value the mapped data-store field contributes to. These
            entries enrich this field mapping; they do not declare additional
            discriminator fields or nested field mappings.
          items:
            type: object
            additionalProperties: false
            properties:
              derivation:
                type: string
                enum:
                  - direct
                  - computed
                  - aggregate
                  - unknown
              projectionLabel:
                type: string
                description: SQL projection or mapper label proven for this contribution.
              applicationFieldPath:
                type: string
                description: >-
                  Unambiguous path within the whole application value, when the
                  scanner can prove one.
            required:
              - derivation
      required:
        - sourceFieldPath
        - destinationFieldPath
      additionalProperties: false
    DiscriminatorEdgeEndpointDisplay:
      type: object
      description: >-
        Display identity for one strand edge endpoint: the endpoint component's
        registry name and a label for the addressed payload, derived from the
        declaration's coordinates. Carried alongside the authoritative address
        so consumers can render an edge without loading the endpoint component.
      properties:
        componentName:
          type: string
        componentType:
          type: string
          enum:
            - CODE
            - DATA_STORE
          description: >-
            Registry component class of the endpoint component: CODE for repo
            components, DATA_STORE for data-store components. A data-store
            endpoint is addressed as one payload named by the store and its
            mapped field paths are the store schema's field names.
        payloadLabel:
          type: string
          description: >-
            The endpoint payload's `payload_name` coordinate when present,
            otherwise the coordinate values joined in key order.
      required:
        - componentName
        - componentType
        - payloadLabel
      additionalProperties: false
    DiscriminatorGroupId:
      type: string
      description: Discriminator group ID from the discriminated engine
      pattern: ^[0-9a-f]{16}$
      example: 0a1b2c3d4e5f6070
    DiscriminatorGroupCoordinates:
      type: object
      description: >-
        Discriminator-group coordinates — the durable address of a group, as
        key-value pairs of the facts the group is grouped by. Keys are the
        discriminator config's group_by dimensions for the group's level,
        verbatim; the dimension vocabulary is defined by the config, not by this
        API. Values are the exact grouping facts; null is the engine's null
        coordinate (fact unknown). Edges and BYO metadata attach to lineage by
        these coordinates, never by group ID (group IDs are derived from
        coordinates by the discriminator engine and are only stable within one
        discriminator config).
      additionalProperties:
        description: >-
          A grouping fact. The engine's coordinate value algebra: null, boolean,
          integer, string, or array of strings.
        anyOf:
          - type: 'null'
          - type: boolean
          - type: integer
          - type: string
          - type: array
            items:
              type: string
    DiscriminatorPayloadDisplay:
      type: object
      description: >-
        Render-only identity for a payload group, sourced from the roll-up's
        boundary pair rather than from the group's coordinates.


        Display and coordinates are two separate vocabularies and may not be
        mixed. Display values are read by key and rendered; their field names
        and arity are fixed by this contract. Coordinates are copied verbatim
        into writes and compared as whole objects; their dimensions belong to
        the discriminator config and may change. Deriving one from the other in
        either direction is always a bug: a label parsed back into an address
        dangles, and an address rendered as a label goes stale the moment the
        config changes.
      properties:
        ingress:
          $ref: '#/components/schemas/DiscriminatorPayloadEndpoint'
          description: The ingress end of the path.
        egress:
          description: >-
            The egress end of the path, or null where the roll-up attributed no
            single egress to this payload group. Consumers detect the
            unattributed case by `egress === null` — never by inspecting
            coordinates.
          anyOf:
            - $ref: '#/components/schemas/DiscriminatorPayloadEndpoint'
            - type: 'null'
        label:
          type: string
          description: >-
            Pre-composed label for the payload, spanning both ends when `egress`
            is present and naming the ingress alone when it is null. Not a
            parseable format: a consumer that needs the ends separately reads
            `ingress` and `egress`, and one that needs an affordance for the
            unattributed case branches on `egress === null`.
      required:
        - ingress
        - egress
        - label
      additionalProperties: false
    DiscriminatorGraphFieldMapping:
      type: object
      description: >-
        One field-mapping row of a payload group in the graph read's
        `detailLevel=fields` mode: the render-only field names plus the
        projected origin and suppression state. Deliberately narrower than the
        per-component `DiscriminatorData` row — no addresses, group ids, code
        paths or anchors — because a graph consumer draws wires and status, and
        writes are addressed through the parent payload group's coordinates.
      properties:
        ingressField:
          description: >-
            The row's ingress field name, or null where the grouping fact is
            absent or is not a string.
          anyOf:
            - type: string
            - type: 'null'
        egressField:
          description: >-
            The row's egress field name, or null where the grouping fact is
            absent or is not a string.
          anyOf:
            - type: string
            - type: 'null'
        fieldMappingKind:
          type: string
          description: The field_mapping_kind coordinate.
          enum:
            - DataFlow
            - KeyValueBridge
            - ControlFlow
        origin:
          type: string
          description: >-
            Declaration provenance for the field mapping: SCAN (engine evidence
            only), BYO_ADD (user-declared, absent from the scan), BYO_CHANGE
            (user-declared over a scan-backed group).
          enum:
            - SCAN
            - BYO_ADD
            - BYO_CHANGE
        suppressed:
          type: boolean
          description: >-
            True when the latest suppression event for this field mapping's
            exact group address is a suppression.
      required:
        - ingressField
        - egressField
        - origin
        - suppressed
      additionalProperties: false
    DiscriminatorLevel:
      type: string
      description: >-
        A level in the product_canonical group hierarchy. `payload` is the root
        level; `field_mapping` is its child. The group_by dimensions for each
        level are defined by the config, not enumerated by this API (see
        DiscriminatorGroupCoordinates).
      enum:
        - payload
        - field_mapping
    DiscriminatorGroupAncestor:
      type: object
      description: >-
        One ancestor group in a canonical address chain. Ancestors are ordered
        root-to-immediate-parent: a `field_mapping` carries its `payload`, and a
        `payload` carries none. The chain's depth and each level's coordinate
        dimensions are the discriminator config's, not this API's — copy an
        ancestor's coordinates verbatim rather than rebuilding them. The service
        derives the parent chain from these coordinates; clients never supply an
        authoritative parent group ID.
      properties:
        level:
          $ref: '#/components/schemas/DiscriminatorLevel'
        coordinates:
          $ref: '#/components/schemas/DiscriminatorGroupCoordinates'
      required:
        - level
        - coordinates
      additionalProperties: false
    DiscriminatorPayloadEndpoint:
      type: object
      description: >-
        Display identity for one end of a payload path, lifted from the
        roll-up's strand provenance. Render-only: an endpoint is not an address,
        is not guaranteed unique, and must never be parsed back into coordinates
        or copied into a write.
      properties:
        name:
          type: string
          description: >-
            Short form of `qualifiedName` for dense UI — the segment after the
            last `.` when the name is dotted, otherwise the whole name.
        qualifiedName:
          type: string
          description: >-
            The engine boundary name, in the roll-up's start_name/end_name
            vocabulary (often a fully qualified class or callee name). This is
            the same vocabulary the explorer's `boundary:{side}:{name}` trace id
            is built from.
        site:
          type: string
          description: >-
            Unambiguous source site shared by the strands represented at this
            end of the payload group, as emitted by strand provenance. Omitted
            when the group contains no source site or contains several distinct
            sites. This value is render-only and never participates in
            discriminator addressing.
      required:
        - name
        - qualifiedName
      additionalProperties: false
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.