packages feed

gachi-sync-0.1.0.0: src/Gachi/Sync/Catalog.hs

{-# LANGUAGE OverloadedStrings #-}

-- | Module: Gachi.Sync.Catalog
-- Description: Canonical shared asset catalog for cross-repository synchronization
--
-- This module implements pure, deterministic template generators for shared
-- ecosystem assets conforming to the Standardization Matrix (~/src/PLAN.md §1.A).
--
-- = Architectural Context & Invariants
--
-- In accordance with Note [Ecosystem Standardization Invariants]
-- [ref:note-ecosystem-standardization], all checkouts in ~/src/* maintain
-- bit-identical formatting profiles, zero-hint linter policies, Git hooks,
-- forge-tiered CI configurations, and AI agent advisory context.
--
-- == Invariant: Deterministic Configuration Synthesis
--
-- Configuration drift is the primary vector for friction in multi-package and
-- multi-repository ecosystems. When different repositories maintain slightly
-- divergent formatting configurations or compiler warning levels:
--
-- 1. __Diff Noise:__ Cross-cutting refactors touching multiple repositories
--    produce massive cosmetic diffs caused by differing indentation, import
--    sorting rules, or column limits.
-- 2. __Toolchain Inconsistencies:__ A code pattern accepted by one repository's
--    linter or compiler invocation triggers fatal warnings in another.
-- 3. __Agent Cognitive Overhead:__ AI assistants waste context tokens discovering
--    local quirks rather than focusing on domain-specific logic.
--
-- This catalog resolves configuration drift by providing an authoritative,
-- single-source-of-truth implementation for all shared configuration assets.
-- All functions in this module are referentially transparent, total, and free of
-- ambient I/O side effects: they evaluate strictly from a 'Project' specification
-- to 'Text' (or are constant 'Text' stanzas).
--
-- = When to Use This Module
--
-- * Inspecting canonical configuration stanzas during repository audits ('Gachi.Sync.Audit').
-- * Synchronizing shared infrastructure files across ecosystem checkouts ('gachi sync').
-- * Initializing new repositories with turnkey toolchain stanzas ('gachi init').
--
-- = Worked Example
--
-- >>> import Gachi.Schema.Project (defaultProject, Author(..))
-- >>> import Gachi.Sync.Catalog
-- >>> let proj = defaultProject "gongju" (Author "Nadia" "nadia@example.com")
-- >>> "indentation: 2" `Data.Text.isInfixOf` fourmoluTemplate
-- True
-- >>> "./bin/gongju-verify" `Data.Text.isInfixOf` githubCiTemplate proj
-- True
module Gachi.Sync.Catalog
  ( -- * Code Formatting Profiles (Dimension 2)
    fourmoluTemplate
  , rustfmtTemplate
  , clangFormatTemplate

    -- * Static Analysis & Linters (Dimension 3)
  , hlintTemplate

    -- * Build System Conventions (Dimension 4)
  , cabalProjectTemplate
  , cabalProjectLocalTemplate

    -- * Git Governance & Hooks (Dimension 5)
  , gitmessageTemplate
  , tagrefConfigTemplate
  , commitMsgHookTemplate
  , preCommitHookTemplate

    -- * Forge-Tiered CI Workflows (Dimension 7)
  , githubCiTemplate
  , gitlabCiTemplate
  , woodpeckerCiTemplate

    -- * Agent Advisory & Rules (Dimension 9)
  , agentsTemplate
  , claudeTemplate
  , commitAttributionRuleTemplate
  , codeNavigationRuleTemplate
  , compilerVerificationRuleTemplate
  , documentationPrecedenceRuleTemplate

    -- * Physical Verification Harnesses
  , verifyScriptTemplate
  , tagrefScriptTemplate
  , linkcheckScriptTemplate
  , clocScriptTemplate
  , generateTagsTemplate
  ) where

import Data.Text (Text)
import qualified Data.Text as T

import Gachi.Schema.Project (Project)
import Gachi.Sync.CI
  ( defaultGitHubSpec
  , defaultGitLabSpec
  , defaultWoodpeckerSpec
  , generateGitHubWorkflow
  , generateGitLabWorkflow
  , generateWoodpeckerWorkflow
  )
import Gachi.Scaffold.Templates
  ( agentsTemplate
  , cabalProjectLocalTemplate
  , cabalProjectTemplate
  , claudeTemplate
  , clocScriptTemplate
  , commitMsgHookTemplate
  , generateTagsTemplate
  , gitmessageTemplate
  , hlintTemplate
  , linkcheckScriptTemplate
  , preCommitHookTemplate
  , tagrefConfigTemplate
  , tagrefScriptTemplate
  , verifyScriptTemplate
  )

--------------------------------------------------------------------------------
-- 1. Code Formatting Profiles (Dimension 2)
--------------------------------------------------------------------------------

-- | Canonical Fourmolu configuration enforcing deterministic, AST-preserving Haskell layout.
--
-- == Formatting Invariants & Design Decisions
--
-- * __Indentation:__ Fixed 2-space indentation depth across all syntactic forms.
-- * __Column Limit:__ Pinned to 100 characters, striking a balance between wide-screen
--   readability and side-by-side terminal diffing.
-- * __Function Arrows:__ Trailing arrows (@->@ at the end of lines) preserving
--   visual alignment in multi-argument type signatures.
-- * __Comma Style:__ Leading commas in multi-line export lists, record updates,
--   and tuple literals to minimize git diff noise during item additions.
-- * __Record Style:__ Aligned record field declarations ensuring vertical alignment
--   of field names, colons, and types.
-- * __Custom Infix Fixities:__ Registers custom row-polymorphism operator fixities
--   (@:=@, @.==@, @.#@) used throughout the polytropos engine to prevent Fourmolu
--   from breaking natural mathematical expression grouping.
fourmoluTemplate :: Text
fourmoluTemplate = T.unlines
  [ "# Fourmolu configuration for standardized ecosystem Haskell repositories"
  , "# Enforces AST-preserving layout for open row lists, record syntax, and operator fixities."
  , ""
  , "indentation: 2"
  , "column-limit: 100"
  , "function-arrows: trailing"
  , "comma-style: leading"
  , "record-style: aligned"
  , "import-export-style: diff-friendly"
  , "import-grouping: legacy"
  , "indent-wheres: true"
  , "record-brace-space: true"
  , "newlines-between-decls: 1"
  , "haddock-style: multi-line"
  , "let-style: auto"
  , "in-style: right-align"
  , "if-style: indented"
  , "single-constraint-parens: never"
  , "single-deriving-parens: always"
  , "sort-constraints: false"
  , "sort-derived-classes: false"
  , "sort-deriving-clauses: false"
  , "trailing-section-operators: true"
  , "unicode: never"
  , "respectful: true"
  , ""
  , "fixities:"
  , "  - \"infixr 5 :=\""
  , "  - \"infixr 5 .==\""
  , "  - \"infixl 8 .#\""
  ]

-- | Canonical rustfmt configuration for polyglot Rust components (e.g. asterinas, surd).
--
-- == Polyglot Formatting Invariants
--
-- * __Line Width:__ Pinned to 100 characters to match Haskell and C/C++ limits.
-- * __Tab Spaces:__ 4-space tab indentation conforming to standard Rust idioms.
-- * __Edition:__ Edition 2021/2024 idioms with modern closure and macro formatting.
-- * __Import Sorting:__ Deterministic lexicographical reordering of @use@ stanzas.
-- * __Module Reordering:__ Canonical module declaration ordering.
rustfmtTemplate :: Text
rustfmtTemplate = T.unlines
  [ "# rustfmt.toml — Ecosystem formatting conventions for Rust components"
  , "max_width = 100"
  , "tab_spaces = 4"
  , "edition = \"2021\""
  , "newline_style = \"Unix\""
  , "use_small_heuristics = \"Default\""
  , "reorder_imports = true"
  , "reorder_modules = true"
  ]

-- | Canonical .clang-format configuration based on Linux kernel and LLVM style.
--
-- == Low-Level Systems Code Formatting
--
-- Applied to C, C++, and CUDA components across low-level operating system trees:
-- * __Style Base:__ Derived from LLVM standard style.
-- * __Indentation:__ 4 spaces with tabs strictly forbidden.
-- * __Brace Placement:__ Attached braces preserving vertical density.
-- * __Include Sorting:__ Deterministic alphabetical sorting of header @#include@ directives.
clangFormatTemplate :: Text
clangFormatTemplate = T.unlines
  [ "# .clang-format — Ecosystem formatting conventions for C/C++ components"
  , "BasedOnStyle: LLVM"
  , "IndentWidth: 4"
  , "ColumnLimit: 100"
  , "UseTab: Never"
  , "BreakBeforeBraces: Attach"
  , "AllowShortFunctionsOnASingleLine: Inline"
  , "SortIncludes: true"
  ]

--------------------------------------------------------------------------------
-- 2. Forge-Tiered CI Workflows (Dimension 7)
--------------------------------------------------------------------------------

-- | GitHub Actions CI workflow for high-resource runners.
--
-- == Asymmetric CI Resource Strategy
--
-- In accordance with Note [Forge-Tiered CI Resource Allocation and Static Gate Partitioning]
-- [ref:note-forge-tiered-ci], commercial forges like GitHub provide high-capacity
-- container runners with ample RAM, multi-core virtual CPUs, and generous monthly
-- allowances. This template evaluates 'generateGitHubWorkflow' using 'defaultGitHubSpec',
-- compiling all packages under GHC 9.14.1 with @--enable-tests@ and running all 5 physical gates.
githubCiTemplate :: Project -> Text
githubCiTemplate = generateGitHubWorkflow defaultGitHubSpec

-- | GitLab CI configuration tailored for resource-constrained community runners.
--
-- == Community Forge Resource Preservation
--
-- Community forges (Framagit, Disroot, etc.) operate on shared infrastructure with
-- limited shared runner compute time and strict memory quotas. Running full GHC
-- compilation on every push would deplete shared runner quotas.
--
-- Per Note [Forge-Tiered CI Resource Allocation and Static Gate Partitioning]
-- [ref:note-forge-tiered-ci], this configuration establishes an asymmetric,
-- lightweight verification pipeline inside @debian:bookworm-slim@:
-- * Executes fast static verification gates (Tagref cross-references and Markdown link check).
-- * Runs the lightweight CLOC comment density audit.
-- * Completely bypasses heavy GHC compilation and link stages, finishing in < 15 seconds.
gitlabCiTemplate :: Project -> Text
gitlabCiTemplate = generateGitLabWorkflow defaultGitLabSpec

-- | Woodpecker CI pipeline configuration for lightweight self-hosted runners.
--
-- == Self-Hosted Container Pipeline
--
-- Generates @.woodpecker.yml@ tailored for Forgejo or Codeberg runners.
-- Executes Tagref, Markdown linkcheck, and CLOC audit inside @debian:bookworm-slim@.
--
-- See Note [Forge-Tiered CI Resource Allocation and Static Gate Partitioning]
-- [ref:note-forge-tiered-ci].
woodpeckerCiTemplate :: Project -> Text
woodpeckerCiTemplate = generateWoodpeckerWorkflow defaultWoodpeckerSpec

--------------------------------------------------------------------------------
-- 3. Modular Agent Advisory Rules (Dimension 9)
--------------------------------------------------------------------------------

-- | Rule: Linux kernel RFC 2822 trailer format ('Assisted-by:') and DCO boundaries.
--
-- Establishes the non-negotiable legal and provenance boundary for AI contributions:
-- * __Attribution Format:__ Uses @Assisted-by: Tool (Provider / Model)@ git trailers.
-- * __DCO Invariant:__ AI agents NEVER sign off on Developer Certificate of Origin (@Signed-off-by:@)
--   or claim legal co-authorship (@Co-authored-by:@).
commitAttributionRuleTemplate :: Text
commitAttributionRuleTemplate = T.unlines
  [ "<!--"
  , "SPDX-License-Identifier: EUPL-1.2 OR Apache-2.0"
  , "-->"
  , "# Commit Authoring & AI Attribution Rules"
  , ""
  , "**Status:** ACTIVE RULE · Bounded Context Extension"
  , "**Enforcement:** `.githooks/commit-msg` · `.gitmessage`"
  , ""
  , "## 1. Linux Kernel RFC 2822 Trailer Schema"
  , ""
  , "AI coding assistant attribution must strictly use RFC 2822 trailer format:"
  , ""
  , "1. `Assisted-by:` (Required when AI assisted):"
  , "   - Format: `Assisted-by: <Tool> (<Provider> / <Model>)` or bare `Assisted-by: <Tool>`"
  , "2. `Orchestrated-by:` (Optional when an orchestration framework directed the task):"
  , "   - Format: `Orchestrated-by: <Engine>`"
  , ""
  , "## 2. Legal Boundary: The Developer Certificate of Origin"
  , ""
  , "- NEVER use `Co-authored-by:` or `Co-developed-by:` for AI assistants."
  , "- NEVER add `Signed-off-by:` on an AI's behalf."
  ]

-- | Rule: Token-saving code navigation funnel (tags, ripgrep, ast-grep, slicing).
--
-- Guides AI agents to conserve context window tokens through hierarchical exploration:
-- 1. Symbol jump via generated @./tags@ (cheapest token cost).
-- 2. Precision line slicing via @view_file@ with @StartLine@ and @EndLine@.
-- 3. Avoid indiscriminate full-file views that exhaust context budgets.
codeNavigationRuleTemplate :: Text
codeNavigationRuleTemplate = T.unlines
  [ "<!--"
  , "SPDX-License-Identifier: EUPL-1.2 OR Apache-2.0"
  , "-->"
  , "# Token-Saving Code Navigation Funnel"
  , ""
  , "**Status:** ACTIVE RULE · Bounded Context Extension"
  , ""
  , "Always follow the token-conservation funnel when exploring code:"
  , "1. `./tags` symbol jump via ripgrep/grep (cheapest token cost)."
  , "2. Targeted file slice viewing (view_file with StartLine/EndLine)."
  , "3. Avoid full-file reading when symbol lookups suffice."
  ]

-- | Rule: Zero-log compiler verification and zero-contamination policy.
--
-- Mandates complete mechanical verification before every commit:
-- * Zero warnings tolerated under @-Wall -Wcompat -Wredundant-constraints@.
-- * All five physical verification gates (@./bin/<project>-verify@) must pass cleanly.
-- * Strict prohibition against unverified code commits or broken tests.
compilerVerificationRuleTemplate :: Text
compilerVerificationRuleTemplate = T.unlines
  [ "<!--"
  , "SPDX-License-Identifier: EUPL-1.2 OR Apache-2.0"
  , "-->"
  , "# Compiler Verification & Zero-Contamination Rules"
  , ""
  , "**Status:** ACTIVE RULE · Bounded Context Extension"
  , ""
  , "- Zero warnings tolerated under `-Wall -Wcompat -Wredundant-constraints`."
  , "- All 5 physical verification gates (`./bin/<project>-verify`) must pass."
  , "- Never commit broken builds, failing tests, or unverified changes."
  ]

-- | Rule: Precedence rule and the two-file operational loop.
--
-- Specifies the relationship between code, documentation, and session state:
-- * __Precedence:__ Code wins at runtime; notes corrected regardless.
-- * __Two-File Loop:__ Always update @PLAN.md@ and @STATE.md@ before concluding sessions.
-- * __Design Canonicity:__ Design documents are load-bearing engineering artifacts.
documentationPrecedenceRuleTemplate :: Text
documentationPrecedenceRuleTemplate = T.unlines
  [ "<!--"
  , "SPDX-License-Identifier: EUPL-1.2 OR Apache-2.0"
  , "-->"
  , "# Documentation Precedence & Operational Loop"
  , ""
  , "**Status:** ACTIVE RULE · Bounded Context Extension"
  , ""
  , "1. Precedence rule: Code wins at runtime; notes corrected regardless."
  , "2. Two-file loop: Always update `PLAN.md` and `STATE.md` before concluding sessions."
  , "3. Design documents are load-bearing; keep anchors and references synchronized."
  ]