Imports:
  - Types:
      - AST
    Usages:
      - loading
    From: goga/ast
  - Types:
      - load_project_config
      - ProjectConfig
    Usages:
      - project-configuration
    From: goga/config
  - Types:
      - ConfigHooks
      - ConfigOverlay
    Usages:
      - checkpoints
    From: goga/config/hooks

Usages:
  click: .goga/usages/cooks/click.md
  conventions: .goga/usages/conventions.md
  beautiful_yaml: .goga/usages/cooks/beautiful_yaml.md

Annotations: |
  The `conventions` practice is used for:
  - working with the codebase
  - organizing the REPL development loop
  - debugging and testing
  - organizing test infrastructure
  - understanding general development and testing principles and rules in the project
  Use the `click` practice to create CLI commands.

  Use the `checkpoints` practice for the config amendment checkpoint at
  the project-configuration load moment — the command loads the authored
  configuration, delivers the checkpoint, consumes the effective
  configuration of the returned `ConfigOverlay`, and prints the amendment
  summary lines to stderr.

  Use `project-configuration` to consume the optional lint section via
  `load_project_config` (the single config entrypoint); .goga/config.yml is
  optional for lint — its absence OR invalidity runs lint unfiltered (lint is
  decoupled from config validity).

---

"lint(path: str = '.')":
  location: lint.py
  annotations: |
    Validates CODEMANIFEST files across the project, honoring the optional
    lint.ignore section of .goga/config.yml by excluding matching directories
    from AST traversal.

    `path`: directory path for CWD context initialization

    Algorithm:
    - Set CWD to the specified `path`
    - Derive ignore: load project configuration via `load_project_config`
      (returns a `ProjectConfig`); a successful load delivers the config
      amendment checkpoint per the `checkpoints` practice via the
      `ConfigHooks` checkpoint surface — amend_config(config=...) — and
      derives ignore from the effective configuration of the
      `ConfigOverlay` —
      when its lint is None -> ignore=None; otherwise
      ignore=cfg.lint.ignore; a failed or absent load runs lint
      unfiltered and offers no checkpoint — nothing was loaded. A
      checkpoint failure on a successful load stops the command with a
      clean click.ClickException — ValueError (the hard action) and
      ImportError (a broken tool package facade) both wrap; it is
      never treated as config-absent. Treat ANY
      loader exception (OSError — covering FileNotFoundError for an
      absent/empty file plus IsADirectoryError/PermissionError when
      unreadable; KeyError, ValueError, yaml.YAMLError) as ignore=None —
      config is optional for lint and lint MUST NOT fail or change its
      exit code due to a present-but-invalid config (run unfiltered).
      Never let a raw loader exception surface as a traceback and never
      let it change lint's exit code.
    - Instantiate `AST` (passing `path` and the derived ignore) and load the
      project via the `loading` practice
    - Print all errors in the defined format
    - Print the validation summary

    Error format:
    ```
    [rule_name] <message>
      --> <path>
          ---
          <yaml_data>
    ```

    Summary format:
    ```
    goga lint
    -------------------------
    cells: <N> errors: <M>
    ```
    Where <N> is the number of validated cells, <M> is the count of detected errors.

    Requirements:
    - Output YAML data using the `beautiful_yaml` practice
    - Strict indentation: [rule_name] at column 0, --> indented 2 spaces,
      --- separator indented 6 spaces, YAML data indented 6 spaces per line
    - Render [rule_name] in red
    - Append the summary after all errors, preceded by a blank line
    - Exit with code 1 on errors, 0 otherwise
    - When .goga/config.yml or the lint section is absent, ignore is None in
      both cases (no directories excluded)
    - ANY loader exception (OSError, KeyError, ValueError, yaml.YAMLError) on
      a present-but-invalid config MUST be treated as ignore=None — lint MUST
      NOT fail or change its exit code due to config;
      lint is decoupled from config validity
    - ignore is passed verbatim to `AST`; lint performs no path normalization
      or glob interpretation — `AST` owns the matching semantics
    - The amendment summary lines of the `ConfigOverlay` print to stderr
      (nothing when empty)

    Constraints:
    - Do NOT require .goga/config.yml for lint to run — FileNotFoundError is
      treated as "no ignore, proceed", not an error
    - Do NOT fail lint on a present-but-invalid .goga/config.yml — treat every
      loader exception (OSError, KeyError, ValueError, yaml.YAMLError) as
      ignore=None; lint is decoupled from config validity
    - Do NOT interpret glob patterns in ignore entries — they flow through to
      `AST`, which documents them as unsupported

---

Author: Goga
CreatedAt: 20/05/26

Description: |
  Project-wide CODEMANIFEST validation command
