# *********************************************** #
# Manifest defining the visitor for each CODEMANIFEST document #
# *********************************************** #

Imports:
  - Types:
      - DocumentRoot
    From: goga/ast/nodes
  - Types:
      - Factory
    From: goga/ast/factory
  - Types:
      - ASTRuleError
      - DocumentRuleError
      - DocumentNotFoundError
    From: goga/ast/errors
  - Types:
      # Document-level rules
      - ImportsCanNotBeEmpty
      - ImportItemIsValid
      - ImportUsageExists
      - ImportHasValidFromPath
      - ImportHasNotDuplicate
      - AllUsagesIsUsed
      - AnnotationLinksExists
      - UsageLinksHasNotConflicts
      - EntitiesAndRoutinesHasNotConflicts
      - MutationExists
      - MutationIsValid
      - ReturnTypeHasLink
      - EmbeddedEntityCanNotHasMutations
      - ImportsHasOnlyValidKeys
      - EntityHasOnlyValidKeys
      - RoutineHasOnlyValidKeys
      - ImportIsUsed
      - SignatureIsValid
      - LocationIsRequired
      - UsageFilepathExists
      - UsageUrlIsAccessible
      # Project-level rules
      - ImportTypeExists
      - ImportsHasNotCyclicalDeps
      - EmbeddedTypeHasLowLevel
    From: goga/ast/rules

Usages:
  conventions: .goga/usages/conventions.md
  nodes: |
    Consumer uses the manifest goga/ast/nodes and its API to work with document structure.
  factory: |
    Instantiate a CODEMANIFEST document using `Factory`.

    ```python
    factory = Factory("path/to/dir/with/codemanifest")
    document = factory.create()
    ```

    Navigate the resulting document via the `DocumentRoot` API.
  visitor: |
    Consumer uses the manifest goga/ast/visitor and its API to analyze a single CODEMANIFEST document.
  analyzer: |
    Consumer uses the manifest goga/ast/analyzer and its API to analyze the entire tree of CODEMANIFEST documents.
  testing: |
    Integration tests for `AST` rules.

    Directory structure:
    - tests/.project/<rule_name>/ — test fixture directory containing CODEMANIFEST and .expected.yaml
    - Helper directories are co-located with the suffix "_helper" when additional files are required.

    .expected.yaml format:
    ```
    errors:
      - rule: <rule_name>
        message: "<exact error message>"
        document_path: "<normalized relative path>"
        node_data: <dict — exact node.data>
    ```

    A single parameterized test in test_project_integration.py:
    - Scans tests/.project/ and loads AST(.project/)
    - Asserts len(errors) and performs strict field-by-field comparison on each error.

Annotations: |
  When developing and testing: follow the practice `conventions`.
  When adding a new rule: create an integration test following the practice `testing`.

---

"AST(path: str)":
  location: ast.py
  annotations: |
    The `AST` class recursively loads the tree of CODEMANIFEST documents.

    `path`: the root path from which the document tree is loaded.
  properties:
    tree -> list[DocumentRoot]: |
      The document tree of the project.
      Contains top-level graph vertices. Consumer traverses from these vertices using practice `nodes`.
    errors -> list[ASTRuleError | DocumentRuleError]: |
      The list of validation errors produced after analysis.
  methods:
    load(): |
      Loads the document tree starting at the specified path.

      Algorithm:
      - Recursively traverse each subdirectory starting from the specified path
      - When a CODEMANIFEST file is found at the directory root:
        - Create the document via practice `factory`
        - Append as a top-level vertex if at the root of the hierarchy
        - Attach as a child to the parent document via practice `nodes`
      - Resolve embedded types against original types in the document tree:
        For each embedded type in entities/routines, locate the matching non-embedded original type by name:
        - Enrich the node with original metadata: signature, annotations, properties, methods
        - Update location to the original document's path
        - Preserve from the factory node: mutations, data
        - If the original is a routine but embedded under entities —
          remove from entities, create RoutineTypeNode, and add to routines
        - If the original is an entity but embedded under routines —
          remove from routines, create EntityTypeNode, and add to entities
      - Run per-document analysis via practice `visitor`
      - Run tree-wide analysis via practice `analyzer`

      Per-document rules:
      - `ImportsCanNotBeEmpty`
      - `ImportItemIsValid`
      - `ImportUsageExists`
      - `ImportHasValidFromPath`
      - `ImportHasNotDuplicate`
      - `AllUsagesIsUsed`
      - `AnnotationLinksExists`
      - `UsageLinksHasNotConflicts`
      - `EntitiesAndRoutinesHasNotConflicts`
      - `MutationExists`
      - `MutationIsValid`
      - `ReturnTypeHasLink`
      - `EmbeddedEntityCanNotHasMutations`
      - `ImportsHasOnlyValidKeys`
      - `EntityHasOnlyValidKeys`
      - `RoutineHasOnlyValidKeys`
      - `ImportIsUsed`
      - `SignatureIsValid`
      - `LocationIsRequired`
      - `UsageFilepathExists`
      - `UsageUrlIsAccessible`

      Tree-wide rules:
      - `ImportTypeExists`
      - `ImportsHasNotCyclicalDeps`
      - `EmbeddedTypeHasLowLevel`

    "document(path: str) -> found_document:DocumentRoot": |
      Resolves and returns the document at the given path.

      `path`: path to the directory containing the CODEMANIFEST file.

      `found_document`: the resolved document.

      Requirements:
      - Handle all path formats:
        - Relative with dot prefix: ./path/path
        - Relative without prefix: path/path
        - Absolute: /path/path
      - Document lookup must run in O(1) time.
      - Raise `DocumentNotFoundError` when the document is not found.

---

Author: Mikhail Trifonov
CreatedAt: 11/04/26

Description: |
  Defines a project that constructs and validates a tree of CODEMANIFEST documents.
