code-standards 8.144.0__tar.gz → 8.147.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. {code_standards-8.144.0 → code_standards-8.147.0}/PKG-INFO +4 -2
  2. {code_standards-8.144.0 → code_standards-8.147.0}/README.md +2 -0
  3. {code_standards-8.144.0 → code_standards-8.147.0}/pyproject.toml +2 -2
  4. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/api.py +63 -13
  5. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/cli-reference.v1.json +2 -2
  6. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/manifest.py +1 -1
  7. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/repository_baseline.py +5 -2
  8. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/scaffold.py +6 -1
  9. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/baseline.py +33 -1
  10. code_standards-8.147.0/src/sarj_standards/libs/diagnostics/initial_import.py +142 -0
  11. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/docs.py +11 -0
  12. {code_standards-8.144.0 → code_standards-8.147.0}/.gitignore +0 -0
  13. {code_standards-8.144.0 → code_standards-8.147.0}/LICENSE +0 -0
  14. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/__init__.py +0 -0
  15. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/__main__.py +0 -0
  16. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/_meta.py +0 -0
  17. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/cli/__init__.py +0 -0
  18. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/cli/main.py +0 -0
  19. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/Mintfile.mobile.strict +0 -0
  20. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/LICENSE.actions +0 -0
  21. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/LICENSE.cronstrue +0 -0
  22. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/LICENSE.yaml +0 -0
  23. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/generate.mts +0 -0
  24. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/index.mts +0 -0
  25. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/package-lock.json +0 -0
  26. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/package.json +0 -0
  27. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser/upstream.json +0 -0
  28. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/action-parser.cjs +0 -0
  29. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/actionlint.strict.yaml +0 -0
  30. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/basedpyright.python315-watch.json +0 -0
  31. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/basedpyright.strict.json +0 -0
  32. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/checkov.strict.yml +0 -0
  33. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/compile-eslint.mts +0 -0
  34. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/detekt.strict.yml +0 -0
  35. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/devops-verification.v1.json +0 -0
  36. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/doctor.config.json +0 -0
  37. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint-compact-formatter.mts +0 -0
  38. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint-required-policy.mts +0 -0
  39. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint-selected-rules.mts +0 -0
  40. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint.application.mjs +0 -0
  41. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint.peers.json +0 -0
  42. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint.strict.mjs +0 -0
  43. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/eslint.strict.ts +0 -0
  44. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/hadolint.strict.yaml +0 -0
  45. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ktlint.strict.editorconfig +0 -0
  46. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/markdownlint.strict.yaml +0 -0
  47. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/mobile-tools.versions.json +0 -0
  48. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/mobsf.strict.yml +0 -0
  49. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/pyright.strict.json +0 -0
  50. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ruff.application.toml +0 -0
  51. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ruff.cast.toml +0 -0
  52. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ruff.python315-watch.toml +0 -0
  53. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ruff.required.toml +0 -0
  54. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/ruff.strict.toml +0 -0
  55. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/rule-calibration-campaign.v1.json +0 -0
  56. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/rule-inventory.v1.json +0 -0
  57. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/rule-ledger.json +0 -0
  58. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/rule-level-source.mts +0 -0
  59. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/schemas/SKAFFOLD-LICENSE +0 -0
  60. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/schemas/google-build-v1-schema.json +0 -0
  61. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/schemas/google-build-v1.LICENSE +0 -0
  62. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/schemas/skaffold-v4beta7.json +0 -0
  63. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/schemas/upstream-schemas.json +0 -0
  64. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/semgrep-overrides.txt +0 -0
  65. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/shellcheck.strict.rc +0 -0
  66. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/swiftformat.strict +0 -0
  67. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/swiftlint.strict.yml +0 -0
  68. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/taplo.strict.toml +0 -0
  69. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/tflint.strict.hcl +0 -0
  70. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/tflint.version.hcl +0 -0
  71. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/tool-json.mts +0 -0
  72. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/yamllint.strict.yaml +0 -0
  73. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/configs/zizmor.strict.yml +0 -0
  74. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/__init__.py +0 -0
  75. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/__init__.py +0 -0
  76. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/age_transition.py +0 -0
  77. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/configs.py +0 -0
  78. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/devops.py +0 -0
  79. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/doctor.py +0 -0
  80. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/exclusions.py +0 -0
  81. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/hooks.py +0 -0
  82. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/launcher.py +0 -0
  83. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/lifecycle.py +0 -0
  84. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/native_bootstrap.py +0 -0
  85. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/packagemanager.py +0 -0
  86. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/retired_suppressions.py +0 -0
  87. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/service.py +0 -0
  88. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/transaction.py +0 -0
  89. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/upgrade.py +0 -0
  90. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/adoption/uvtool.py +0 -0
  91. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/catalogs/__init__.py +0 -0
  92. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/catalogs/slack_automations.py +0 -0
  93. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/corpus/__init__.py +0 -0
  94. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/corpus/manifest.py +0 -0
  95. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/corpus/snapshot.py +0 -0
  96. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/__init__.py +0 -0
  97. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/analysis.schema.json +0 -0
  98. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/models.py +0 -0
  99. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/serialize.py +0 -0
  100. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/diagnostics/source.py +0 -0
  101. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/filesystem.py +0 -0
  102. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/json_boundary.py +0 -0
  103. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/__init__.py +0 -0
  104. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/_cloudbuild_autofix.py +0 -0
  105. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/action_metadata.py +0 -0
  106. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/analysis.py +0 -0
  107. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/autofix.py +0 -0
  108. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/chart_schemas.py +0 -0
  109. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/cloudbuild.py +0 -0
  110. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/cloudbuild_schema.py +0 -0
  111. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/complexity_baseline.py +0 -0
  112. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/devops_programs.py +0 -0
  113. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/devops_schema.py +0 -0
  114. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/devops_source.py +0 -0
  115. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/devops_tools.py +0 -0
  116. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/duplicate_code.py +0 -0
  117. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/embedded_shell.py +0 -0
  118. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/external.py +0 -0
  119. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/kubernetes_context.py +0 -0
  120. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/library_policy.py +0 -0
  121. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/mobile_tools.py +0 -0
  122. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/policy.py +0 -0
  123. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/prepared_devops.py +0 -0
  124. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/prepared_kubernetes.py +0 -0
  125. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/prepared_native.py +0 -0
  126. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/python_fixes.py +0 -0
  127. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/repo_standards.py +0 -0
  128. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/runner.py +0 -0
  129. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/scheduling.py +0 -0
  130. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/security_tools.py +0 -0
  131. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/shell_ast.py +0 -0
  132. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/shell_format.py +0 -0
  133. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/shell_policy.py +0 -0
  134. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/test_value.py +0 -0
  135. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rule_base.py +0 -0
  136. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rules/__init__.py +0 -0
  137. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rules/_registry.py +0 -0
  138. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rules/_slack_payload.py +0 -0
  139. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rules/cloudbuild_contract.py +0 -0
  140. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/text_rules/slack_event_text_in_mrkdwn.py +0 -0
  141. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/textlint.py +0 -0
  142. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/toml_literals.py +0 -0
  143. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/linting/unused_modules.py +0 -0
  144. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/__init__.py +0 -0
  145. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/_values.py +0 -0
  146. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/artifacts.py +0 -0
  147. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/causality.py +0 -0
  148. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/changes.py +0 -0
  149. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/ci_artifacts.py +0 -0
  150. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/make_checks.py +0 -0
  151. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/metadata_verification.py +0 -0
  152. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/native_test_setup.py +0 -0
  153. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/process.py +0 -0
  154. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/publish.py +0 -0
  155. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/registry.py +0 -0
  156. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/release_age.py +0 -0
  157. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/release_detect.py +0 -0
  158. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/retirement.py +0 -0
  159. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/reviewed_analysis.py +0 -0
  160. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/rollout.py +0 -0
  161. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/status.py +0 -0
  162. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/tags.py +0 -0
  163. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/test_selection.py +0 -0
  164. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/typescript.py +0 -0
  165. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/verification_process.py +0 -0
  166. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/release/wheel_tests.py +0 -0
  167. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/__init__.py +0 -0
  168. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/cli_examples.py +0 -0
  169. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/cli_reference_artifact.py +0 -0
  170. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/cloudbuild_schema_projection.py +0 -0
  171. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/comment_corpus.py +0 -0
  172. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/config_generation.py +0 -0
  173. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/hooks.py +0 -0
  174. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/immutable_git.py +0 -0
  175. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/ledger.py +0 -0
  176. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/repository.py +0 -0
  177. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/ruff_freshness.py +0 -0
  178. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_authoring.py +0 -0
  179. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_catalog_artifact.py +0 -0
  180. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_changes.py +0 -0
  181. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_checkout.py +0 -0
  182. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_dependencies.py +0 -0
  183. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_examples.py +0 -0
  184. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_imports.mts +0 -0
  185. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_inventory_artifact.py +0 -0
  186. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_level_source.py +0 -0
  187. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_lifecycle.py +0 -0
  188. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_maintenance.py +0 -0
  189. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/rule_registration.py +0 -0
  190. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/shell_checks.py +0 -0
  191. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/repository/third_party_catalog_artifact.py +0 -0
  192. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/rules/__init__.py +0 -0
  193. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/rules/catalog.py +0 -0
  194. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/rules/contracts.py +0 -0
  195. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/rules/corpus_runner.py +0 -0
  196. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/rules/evaluation.py +0 -0
  197. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/schema_boundary.py +0 -0
  198. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/setup/__init__.py +0 -0
  199. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/setup/repository.py +0 -0
  200. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/typed_containers.py +0 -0
  201. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/libs/yaml_boundary.py +0 -0
  202. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/py.typed +0 -0
  203. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/schemas/__init__.py +0 -0
  204. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/schemas/_paths.py +0 -0
  205. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/schemas/rule-catalog.v1.json +0 -0
  206. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/schemas/rule-catalog.v1.schema.json +0 -0
  207. {code_standards-8.144.0 → code_standards-8.147.0}/src/sarj_standards/schemas/slack-automations.v1.schema.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code-standards
3
- Version: 8.144.0
3
+ Version: 8.147.0
4
4
  Summary: One deterministic quality gate for Sarj Python, TypeScript, Swift, Kotlin, shell, SQL, IaC, and repository policy.
5
5
  Project-URL: Homepage, https://code-standards.sarj.ai/
6
6
  Project-URL: Documentation, https://code-standards.sarj.ai/cli/
@@ -28,7 +28,7 @@ Requires-Dist: pre-commit==4.7.0
28
28
  Requires-Dist: pydantic==2.14.1
29
29
  Requires-Dist: pyyaml==6.0.3
30
30
  Requires-Dist: referencing==0.37.0
31
- Requires-Dist: repo-standards==6.13.0
31
+ Requires-Dist: repo-standards==6.14.0
32
32
  Requires-Dist: ruff==0.17.2
33
33
  Requires-Dist: sarj-iac-lint==0.30.3
34
34
  Requires-Dist: sarj-python-lint==1.84.0
@@ -67,6 +67,8 @@ New ESLint setups use `eslint.config.ts` and the compiler-checked `eslint.strict
67
67
 
68
68
  Use repeatable `check --rule ENGINE:ID` selectors to select native rules, ESLint rules, or managed security audits. Exclusions, baselines, and severities still apply; Ruff selectors are not supported. Native linters and ESLint execute only selected rules. ESLint retains configured parsers, options, severities, and suppression directives.
69
69
 
70
+ For a history-free initial import, set `SARJ_STANDARDS_INITIAL_IMPORT_SOURCE` only on the initial commit process to the full lowercase object ID of an available source commit with exactly one available parent. HEAD must be an unborn branch; the entire staged tree must equal that commit, tracked worktree files must match the index without hidden index flags, and nonignored files must be staged. Native staged checks compare the source commit with its parent, preserving the usual changed-line failures for findings introduced in that commit while allowing inherited diagnostic budgets. Validation runs before and after analysis; all analyzers and baseline limits still apply. The caller must qualify the source commit separately. Git replacement objects and lazy fetching are disabled; explicitly supplied temporary object alternates may provide the source history without copying it into the new repository. Remove the input and alternates before subsequent commits, pushes, and CI. Invalid or changed import context fails analysis, including clean reports; ordinary checks without this input retain their existing behavior.
71
+
70
72
  Selected ESLint checks apply live inline suppressions and validate selected bulk suppression counts. The complete lint gate owns unused inline-directive and inline-configuration checks: a partial run cannot establish whether an unselected rule's directive is needed.
71
73
 
72
74
  The complete Python and JavaScript/TypeScript source gate requires named, line-local exceptions with concrete reasons. SARJ523 rejects blanket Python waivers, scoped Ruff file/range disables and weakened Pyright source settings; SARJ419 also rejects missing explanations. Bare sarj-noqa markers cannot waive Python, SQL or IaC findings. Required Ruff blanket-ignore checks and an independent ESLint suppression-policy pass remain active despite source disables, consumer rule configuration, rule exclusions and diagnostic baselines. The ESLint pass bans file/range disables, ts-ignore and ts-nocheck while retaining described local ts-expect-error exceptions. Generated-source headers cannot authorize their own waiver; explicit whole-path exclusions retain that boundary. A reason is not proof that an exception is justified. Native parse/read/size failures make checks incomplete. Explicit tool delegation, partial and own-CI options retain their declared scope and coverage notices.
@@ -27,6 +27,8 @@ New ESLint setups use `eslint.config.ts` and the compiler-checked `eslint.strict
27
27
 
28
28
  Use repeatable `check --rule ENGINE:ID` selectors to select native rules, ESLint rules, or managed security audits. Exclusions, baselines, and severities still apply; Ruff selectors are not supported. Native linters and ESLint execute only selected rules. ESLint retains configured parsers, options, severities, and suppression directives.
29
29
 
30
+ For a history-free initial import, set `SARJ_STANDARDS_INITIAL_IMPORT_SOURCE` only on the initial commit process to the full lowercase object ID of an available source commit with exactly one available parent. HEAD must be an unborn branch; the entire staged tree must equal that commit, tracked worktree files must match the index without hidden index flags, and nonignored files must be staged. Native staged checks compare the source commit with its parent, preserving the usual changed-line failures for findings introduced in that commit while allowing inherited diagnostic budgets. Validation runs before and after analysis; all analyzers and baseline limits still apply. The caller must qualify the source commit separately. Git replacement objects and lazy fetching are disabled; explicitly supplied temporary object alternates may provide the source history without copying it into the new repository. Remove the input and alternates before subsequent commits, pushes, and CI. Invalid or changed import context fails analysis, including clean reports; ordinary checks without this input retain their existing behavior.
31
+
30
32
  Selected ESLint checks apply live inline suppressions and validate selected bulk suppression counts. The complete lint gate owns unused inline-directive and inline-configuration checks: a partial run cannot establish whether an unselected rule's directive is needed.
31
33
 
32
34
  The complete Python and JavaScript/TypeScript source gate requires named, line-local exceptions with concrete reasons. SARJ523 rejects blanket Python waivers, scoped Ruff file/range disables and weakened Pyright source settings; SARJ419 also rejects missing explanations. Bare sarj-noqa markers cannot waive Python, SQL or IaC findings. Required Ruff blanket-ignore checks and an independent ESLint suppression-policy pass remain active despite source disables, consumer rule configuration, rule exclusions and diagnostic baselines. The ESLint pass bans file/range disables, ts-ignore and ts-nocheck while retaining described local ts-expect-error exceptions. Generated-source headers cannot authorize their own waiver; explicit whole-path exclusions retain that boundary. A reason is not proof that an exception is justified. Native parse/read/size failures make checks incomplete. Explicit tool delegation, partial and own-CI options retain their declared scope and coverage notices.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "code-standards"
3
- version = "8.144.0"
3
+ version = "8.147.0"
4
4
  description = "One deterministic quality gate for Sarj Python, TypeScript, Swift, Kotlin, shell, SQL, IaC, and repository policy."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -28,7 +28,7 @@ dependencies = [
28
28
  "PyYAML==6.0.3",
29
29
  "jsonschema==4.26.0",
30
30
  "referencing==0.37.0",
31
- "repo-standards==6.13.0",
31
+ "repo-standards==6.14.0",
32
32
  "ruff==0.17.2",
33
33
  "shellcheck-py==0.11.0.1; (sys_platform == 'darwin' and platform_machine == 'arm64') or (sys_platform == 'darwin' and platform_machine == 'x86_64') or (sys_platform == 'linux' and platform_machine == 'x86_64') or (sys_platform == 'win32' and platform_machine == 'AMD64')",
34
34
  "sarj-iac-lint==0.30.3",
@@ -47,6 +47,7 @@ from .libs.diagnostics import (
47
47
  ToolReport as ToolReport,
48
48
  TrustMode as TrustMode,
49
49
  baseline as diagnostic_baseline,
50
+ initial_import,
50
51
  to_github as to_github,
51
52
  to_json as to_json,
52
53
  to_sarif as to_sarif,
@@ -266,6 +267,10 @@ class Standards:
266
267
  python_type_check: bool = True,
267
268
  eslint: bool = True,
268
269
  ) -> AnalysisReport:
270
+ try:
271
+ import_context = initial_import.load(self.root, staged=staged)
272
+ except ValueError as exc:
273
+ return _failed_analysis(self.root, "invalid-input", str(exc))
269
274
  if jobs not in {1, 2}:
270
275
  return _failed_analysis(self.root, "invalid-input", "analysis jobs must be 1 or 2")
271
276
  external = external or bool(upstream_rules.ids)
@@ -279,8 +284,18 @@ class Standards:
279
284
  except (OSError, TypeError, ValueError) as exc:
280
285
  return _failed_analysis(self.root, "invalid-input", str(exc))
281
286
  if prepared_only:
282
- return _prepared_only_analysis(
283
- self.root, adopted, prepared_devops, prepared_targets, paths=paths, rules=rules, trust=normalized_trust
287
+ return _validated_initial_import(
288
+ _prepared_only_analysis(
289
+ self.root,
290
+ adopted,
291
+ prepared_devops,
292
+ prepared_targets,
293
+ paths=paths,
294
+ rules=rules,
295
+ trust=normalized_trust,
296
+ ),
297
+ import_context,
298
+ staged=staged,
284
299
  )
285
300
  try:
286
301
  selection_policy = _selection_policy(self.root, adopted, normalized_mode)
@@ -321,16 +336,24 @@ class Standards:
321
336
  )
322
337
  coverage.extend(_prepared_coverage(adopted, prepared_devops))
323
338
  if not external:
324
- native = report_from_tools(self.root, native_analysis())
325
- changed_scope = _analysis_changed_scope(self.root, native, baseline_budget, staged=staged)
339
+ combined = report_from_tools(self.root, native_analysis())
340
+ changed_scope = _analysis_changed_scope(self.root, combined, baseline_budget, staged=staged)
326
341
  _native_typescript_coverage(selected_groups, adopted, rule_selection, coverage)
327
342
  if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
328
- native = _with_warning_severity(native, _warning_rule_keys(normalized_mode, rule_selection))
329
- return _with_coverage(
330
- _without_baselined_diagnostics(
331
- native, baseline_budget.counts, changed_scope=changed_scope, provenance=baseline_budget.provenance
343
+ combined = _with_warning_severity(combined, _warning_rule_keys(normalized_mode, rule_selection))
344
+ return _validated_initial_import(
345
+ _with_coverage(
346
+ _without_baselined_diagnostics(
347
+ combined,
348
+ baseline_budget.counts,
349
+ changed_scope=changed_scope,
350
+ provenance=baseline_budget.provenance,
351
+ ),
352
+ coverage,
332
353
  ),
333
- coverage,
354
+ import_context,
355
+ staged=staged,
356
+ changed_scope=changed_scope,
334
357
  )
335
358
  coverage.extend(
336
359
  _source_analyzer_coverage(
@@ -375,11 +398,16 @@ class Standards:
375
398
  else frozenset(),
376
399
  upstream_rules=upstream_rules,
377
400
  )
378
- return _with_coverage(
379
- _without_baselined_diagnostics(
380
- combined, baseline_budget.counts, changed_scope=changed_scope, provenance=baseline_budget.provenance
401
+ return _validated_initial_import(
402
+ _with_coverage(
403
+ _without_baselined_diagnostics(
404
+ combined, baseline_budget.counts, changed_scope=changed_scope, provenance=baseline_budget.provenance
405
+ ),
406
+ coverage,
381
407
  ),
382
- coverage,
408
+ import_context,
409
+ staged=staged,
410
+ changed_scope=changed_scope,
383
411
  )
384
412
 
385
413
  def run(
@@ -670,6 +698,28 @@ def _failed_analysis(root: Path, kind: str, message: str) -> AnalysisReport:
670
698
  return AnalysisReport(root, Completion.FAILED, Conclusion.INCONCLUSIVE, (tool,))
671
699
 
672
700
 
701
+ def _validated_initial_import(
702
+ report: AnalysisReport,
703
+ context: initial_import.InitialImport | None,
704
+ *,
705
+ staged: bool,
706
+ changed_scope: diagnostic_baseline.ChangedLineScope | None = None,
707
+ ) -> AnalysisReport:
708
+ failure: str | None = None
709
+ try:
710
+ initial_import.validate(report.root, context, staged=staged)
711
+ except ValueError as exc:
712
+ failure = str(exc)
713
+ if failure is None and context is not None and changed_scope is not None and changed_scope.failed:
714
+ failure = "initial-import changed-line comparison failed"
715
+ if failure is None:
716
+ return report
717
+ return _with_coverage(
718
+ report_from_tools(report.root, (*report.tools, *_failed_analysis(report.root, "invalid-input", failure).tools)),
719
+ report.coverage,
720
+ )
721
+
722
+
673
723
  def _analysis_changed_scope(
674
724
  root: Path,
675
725
  report: AnalysisReport,
@@ -3316,6 +3316,6 @@
3316
3316
  },
3317
3317
  "program": "code-standards",
3318
3318
  "schemaVersion": 1,
3319
- "summary": "Adopt, check, fix, diagnose, and update sarj-ai standards (v8.144.0).",
3320
- "version": "8.144.0"
3319
+ "summary": "Adopt, check, fix, diagnose, and update sarj-ai standards (v8.147.0).",
3320
+ "version": "8.147.0"
3321
3321
  }
@@ -55,7 +55,7 @@ class _UpstreamRuleEngine(StrEnum):
55
55
  LINT_CONFIGS: Final = "code-standards"
56
56
  _PYTHON_LINT: Final = "sarj-python-lint"
57
57
  SIBLING_PACKAGES: Final = (_PYTHON_LINT, "sarj-sql-lint", "sarj-iac-lint")
58
- REPO_STANDARDS_VERSION: Final = "6.13.0"
58
+ REPO_STANDARDS_VERSION: Final = "6.14.0"
59
59
  # Actions can receive delivery fixes independently of the consumer topology policy.
60
60
  REPO_STANDARDS_ACTION_VERSION: Final = "6.13.0"
61
61
  REPO_STANDARDS_REVISION: Final = "c61146c7137c764ac1371a99508771fc255a1767"
@@ -28,7 +28,10 @@ PATH = ".repo-standards/baseline.json"
28
28
  # enabling it still leaves every new finding unaccepted by the warning ratchet.
29
29
  # Policy 28 changes operational-script-tests identities; only empty policy 27
30
30
  # baselines remain compatible. Accepted debt still requires a separate review.
31
- _COMPATIBLE_TRANSITIONS = frozenset({(18, 19), (18, 20), (19, 20), (25, 26), (25, 27), (26, 27)})
31
+ # Policy 29 adds a default-disabled migration warning. Existing finding
32
+ # identities and manifest scope remain unchanged; preserve all accepted debt.
33
+ # Empty policy 27 baselines may compose the reviewed 27 -> 28 -> 29 steps.
34
+ _COMPATIBLE_TRANSITIONS = frozenset({(18, 19), (18, 20), (19, 20), (25, 26), (25, 27), (26, 27), (28, 29)})
32
35
  _POLICY_VERSION = re.compile(rb'("policy_version"\s*:\s*)[0-9]+(?=\s*[,}])')
33
36
 
34
37
 
@@ -59,7 +62,7 @@ def migrate(contents: bytes, manifest: bytes, *, target_policy_version: int) ->
59
62
  if baseline.policy_version == target_policy_version:
60
63
  return contents
61
64
  transition = (baseline.policy_version, target_policy_version)
62
- empty_compatible = transition == (27, 28) and not baseline.fingerprints
65
+ empty_compatible = transition in {(27, 28), (27, 29)} and not baseline.fingerprints
63
66
  if transition not in _COMPATIBLE_TRANSITIONS and not empty_compatible:
64
67
  msg = (
65
68
  f"repository baseline migration {baseline.policy_version} -> {target_policy_version} "
@@ -2399,8 +2399,13 @@ def github_ci_workflow(root: Path, *, ecosystems: Ecosystems | None = None) -> s
2399
2399
  lines.extend(
2400
2400
  (
2401
2401
  " - name: Run standards",
2402
+ " shell: bash",
2402
2403
  " env:",
2403
- " SARJ_STANDARDS_BASE: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}",
2404
+ " SARJ_STANDARDS_BASE: >-",
2405
+ " ${{ !(github.event_name == 'push' && github.event.created &&",
2406
+ " github.event.before == '0000000000000000000000000000000000000000') &&",
2407
+ " (github.event.pull_request.base.sha || github.event.merge_group.base_sha ||",
2408
+ " github.event.before) || '' }}",
2404
2409
  f" run: {runner} check --trust-repository-code --format github",
2405
2410
  )
2406
2411
  )
@@ -10,7 +10,7 @@ from pathlib import Path
10
10
  import re
11
11
  import shutil
12
12
  import subprocess # ruff: ignore[suspicious-subprocess-import] -- fixed read-only git argv.
13
- from typing import TYPE_CHECKING
13
+ from typing import TYPE_CHECKING, TypedDict
14
14
 
15
15
  from pydantic import JsonValue
16
16
 
@@ -18,6 +18,8 @@ from sarj_standards.libs.filesystem import is_link_like
18
18
  from sarj_standards.libs.json_boundary import parse_unique_json
19
19
  from sarj_standards.libs.typed_containers import is_object_mapping
20
20
 
21
+ from . import initial_import
22
+
21
23
 
22
24
  if TYPE_CHECKING:
23
25
  from collections.abc import Iterable, Mapping, Sequence
@@ -48,6 +50,10 @@ class _ChangedPaths:
48
50
  renamed: bool
49
51
 
50
52
 
53
+ class _DiffOptions(TypedDict, total=False):
54
+ env: dict[str, str]
55
+
56
+
51
57
  @dataclass(frozen=True, slots=True)
52
58
  class RuleRemoval:
53
59
  contents: str
@@ -83,9 +89,17 @@ def changed_line_scope(root: Path, *, staged: bool, paths: Iterable[str] | None
83
89
  git = shutil.which("git")
84
90
  if git is None:
85
91
  return ChangedLineScope(frozenset(), {}, failed=True)
92
+ try:
93
+ context = initial_import.load(root, staged=staged)
94
+ except ValueError:
95
+ return ChangedLineScope(frozenset(), {}, failed=True)
96
+ # The validated index equals source; immutable endpoints keep both patch reads on that exact delta.
86
97
  comparison = ("--cached",) if staged else (f"{base}...HEAD",)
98
+ if context is not None:
99
+ comparison = (context.parent, context.source)
87
100
  common = (
88
101
  git,
102
+ *(("--no-replace-objects", "--no-lazy-fetch") if context is not None else ()),
89
103
  "--literal-pathspecs",
90
104
  "-c",
91
105
  "core.quotePath=true",
@@ -101,6 +115,18 @@ def changed_line_scope(root: Path, *, staged: bool, paths: Iterable[str] | None
101
115
  return None
102
116
  if sum(len(os.fsencode(path)) + 1 for path in selected) > _MAX_DIFF_PATH_BYTES:
103
117
  selected = ()
118
+ return _read_changed_scope(root, common, selected, staged=staged, context=context)
119
+
120
+
121
+ def _read_changed_scope(
122
+ root: Path,
123
+ common: tuple[str, ...],
124
+ selected: tuple[str, ...],
125
+ *,
126
+ staged: bool,
127
+ context: initial_import.InitialImport | None,
128
+ ) -> ChangedLineScope:
129
+ options: _DiffOptions = {"env": initial_import.git_environment()} if context is not None else {}
104
130
  try:
105
131
  names = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed Git argv with literal repository-relative paths.
106
132
  (*common, "--name-status", "-z", "--"),
@@ -108,6 +134,7 @@ def changed_line_scope(root: Path, *, staged: bool, paths: Iterable[str] | None
108
134
  check=False,
109
135
  capture_output=True,
110
136
  timeout=30,
137
+ **options,
111
138
  )
112
139
  changes = _changed_paths(names.stdout)
113
140
  if changes.renamed:
@@ -119,11 +146,16 @@ def changed_line_scope(root: Path, *, staged: bool, paths: Iterable[str] | None
119
146
  check=False,
120
147
  capture_output=True,
121
148
  timeout=30,
149
+ **options,
122
150
  )
123
151
  except OSError, ValueError, subprocess.TimeoutExpired:
124
152
  return ChangedLineScope(frozenset(), {}, failed=True)
125
153
  if names.returncode != 0 or patch.returncode != 0:
126
154
  return ChangedLineScope(frozenset(), {}, failed=True)
155
+ try:
156
+ initial_import.validate(root, context, staged=staged)
157
+ except ValueError:
158
+ return ChangedLineScope(frozenset(), {}, failed=True)
127
159
  affected = changes.paths & frozenset(selected) if selected else changes.paths
128
160
  return ChangedLineScope(affected, _changed_lines_from_patch(patch.stdout.decode("utf-8", errors="surrogateescape")))
129
161
 
@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ import os
5
+ from pathlib import Path
6
+ import re
7
+ import shutil
8
+ import subprocess # ruff: ignore[suspicious-subprocess-import] -- bounded, fixed read-only Git argv except index tree materialization.
9
+
10
+
11
+ _SOURCE_ENV = "SARJ_STANDARDS_INITIAL_IMPORT_SOURCE"
12
+ _OID = re.compile(r"[0-9a-f]{40}|[0-9a-f]{64}")
13
+ _GIT_INPUTS = frozenset({"GIT_INDEX_FILE", "GIT_ALTERNATE_OBJECT_DIRECTORIES"})
14
+
15
+
16
+ @dataclass(frozen=True, slots=True)
17
+ class InitialImport:
18
+ source: str
19
+ tree: str
20
+ parent: str
21
+
22
+
23
+ def git_environment() -> dict[str, str]:
24
+ return {
25
+ name: value
26
+ for name, value in os.environ.items() # ruff: ignore[banned-api] -- bind reads to the analyzed checkout while retaining explicit prospective index and object access.
27
+ if not name.startswith("GIT_") or name in _GIT_INPUTS
28
+ }
29
+
30
+
31
+ def load(root: Path, *, staged: bool) -> InitialImport | None:
32
+ source = os.environ.get(_SOURCE_ENV) # ruff: ignore[banned-api] -- explicit process-scoped native initial-import input, never inferred from repository settings.
33
+ if source is None:
34
+ return None
35
+ if not staged or _OID.fullmatch(source) is None:
36
+ msg = f"{_SOURCE_ENV} requires --staged and a full lowercase commit object ID"
37
+ raise ValueError(msg)
38
+ top = _git(root, "rev-parse", "--show-toplevel").removesuffix(b"\n").decode("utf-8", errors="surrogateescape")
39
+ if Path(top).resolve() != root.resolve():
40
+ msg = "initial import requires the analyzed Git worktree root"
41
+ raise ValueError(msg)
42
+ # A symbolic, missing HEAD distinguishes an initial commit from a broken detached checkout.
43
+ branch = _git(root, "symbolic-ref", "--quiet", "HEAD").removesuffix(b"\n").decode("utf-8", errors="surrogateescape")
44
+ if not branch.startswith("refs/heads/"):
45
+ msg = "initial import requires an unborn branch HEAD"
46
+ raise ValueError(msg)
47
+ _git(root, "show-ref", "--verify", "--quiet", branch, allowed=(1,))
48
+ context = _source_commit(root, source)
49
+ if _git(root, "write-tree").strip().decode("ascii") != context.tree:
50
+ msg = "initial-import index must exactly match the source commit tree"
51
+ raise ValueError(msg)
52
+ flags = _git(root, "ls-files", "-v", "-z").split(b"\0")
53
+ if any(entry and entry[:1] != b"H" for entry in flags):
54
+ msg = "initial import requires verifiable index flags"
55
+ raise ValueError(msg)
56
+ # Stat-only differences can return one with no content diff; numstat also captures mode/type changes.
57
+ if _git(
58
+ root,
59
+ "-c",
60
+ "core.filemode=true",
61
+ "diff",
62
+ "--exit-code",
63
+ "--numstat",
64
+ "-z",
65
+ "--no-ext-diff",
66
+ "--no-textconv",
67
+ "--ignore-submodules=none",
68
+ "--",
69
+ allowed=(0, 1),
70
+ ):
71
+ msg = "initial-import tracked worktree must match the index"
72
+ raise ValueError(msg)
73
+ if _git(root, "ls-files", "--others", "--exclude-standard", "-z"):
74
+ msg = "initial import requires all nonignored worktree files to be staged"
75
+ raise ValueError(msg)
76
+ _git(
77
+ root,
78
+ "diff",
79
+ "--no-ext-diff",
80
+ "--no-textconv",
81
+ "--ignore-submodules=none",
82
+ "--numstat",
83
+ "-z",
84
+ context.parent,
85
+ context.source,
86
+ "--",
87
+ )
88
+ return context
89
+
90
+
91
+ def validate(root: Path, context: InitialImport | None, *, staged: bool) -> None:
92
+ source = os.environ.get(_SOURCE_ENV) # ruff: ignore[banned-api] -- reject context activation as well as removal during an analysis transaction.
93
+ if (context is None and source is not None) or (context is not None and load(root, staged=staged) != context):
94
+ msg = "initial-import source context changed during analysis"
95
+ raise ValueError(msg)
96
+
97
+
98
+ def _source_commit(root: Path, source: str) -> InitialImport:
99
+ if _git(root, "cat-file", "-t", source) != b"commit\n":
100
+ msg = "initial-import source must be an available commit"
101
+ raise ValueError(msg)
102
+ headers = _git(root, "cat-file", "commit", source).split(b"\n\n", 1)[0].splitlines()
103
+ trees = [line.removeprefix(b"tree ").decode("ascii") for line in headers if line.startswith(b"tree ")]
104
+ parents = [line.removeprefix(b"parent ").decode("ascii") for line in headers if line.startswith(b"parent ")]
105
+ if len(trees) != 1 or len(parents) != 1 or any(_OID.fullmatch(oid) is None for oid in (*trees, *parents)):
106
+ msg = "initial-import source must have exactly one available parent"
107
+ raise ValueError(msg)
108
+ if _git(root, "cat-file", "-t", parents[0]) != b"commit\n":
109
+ msg = "initial-import source parent must be an available commit"
110
+ raise ValueError(msg)
111
+ return InitialImport(source, trees[0], parents[0])
112
+
113
+
114
+ def _git(root: Path, *arguments: str, allowed: tuple[int, ...] = (0,)) -> bytes:
115
+ git = shutil.which("git")
116
+ if git is None:
117
+ msg = "initial import requires Git"
118
+ raise ValueError(msg)
119
+ try:
120
+ result = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed Git argv, no shell, replacement objects or network fetches.
121
+ (
122
+ git,
123
+ "--no-replace-objects",
124
+ "--no-lazy-fetch",
125
+ "--literal-pathspecs",
126
+ "-c",
127
+ "diff.autoRefreshIndex=false",
128
+ *arguments,
129
+ ),
130
+ cwd=root,
131
+ check=False,
132
+ capture_output=True,
133
+ timeout=30,
134
+ env=git_environment(),
135
+ )
136
+ except (OSError, ValueError, subprocess.TimeoutExpired) as error:
137
+ msg = "cannot validate initial-import Git state"
138
+ raise ValueError(msg) from error
139
+ if result.returncode not in allowed:
140
+ msg = f"cannot validate initial-import Git state: {arguments[0]} failed"
141
+ raise ValueError(msg)
142
+ return result.stdout
@@ -318,6 +318,17 @@ def _package_usage(name: str, engine: str | None) -> str:
318
318
  "Exclusions, baselines, and severities still apply; Ruff selectors are not supported. "
319
319
  "Native linters and ESLint execute only selected rules. ESLint retains configured parsers, options, "
320
320
  "severities, and suppression directives.\n\n"
321
+ "For a history-free initial import, set `SARJ_STANDARDS_INITIAL_IMPORT_SOURCE` only on the initial "
322
+ "commit process to the full lowercase object ID of an available source commit with exactly one available "
323
+ "parent. HEAD must be an unborn branch; the entire staged tree must equal that commit, tracked worktree "
324
+ "files must match the index without hidden index flags, and nonignored files must be staged. Native staged "
325
+ "checks compare the source commit with its parent, preserving the usual changed-line failures for findings "
326
+ "introduced in that commit while allowing inherited diagnostic budgets. Validation runs before and after "
327
+ "analysis; all analyzers and baseline limits still apply. The caller must qualify the source commit "
328
+ "separately. Git replacement objects and lazy fetching are disabled; explicitly supplied temporary object "
329
+ "alternates may provide the source history without copying it into the new repository. Remove the input "
330
+ "and alternates before subsequent commits, pushes, and CI. Invalid or changed import context fails "
331
+ "analysis, including clean reports; ordinary checks without this input retain their existing behavior.\n\n"
321
332
  "Selected ESLint checks apply live inline suppressions and validate selected bulk suppression "
322
333
  "counts. The complete lint gate owns unused inline-directive and inline-configuration checks: "
323
334
  "a partial run cannot establish whether an unselected rule's directive is needed.\n\n"