code-standards 7.0.4__tar.gz → 7.1.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 (106) hide show
  1. {code_standards-7.0.4 → code_standards-7.1.0}/PKG-INFO +2 -2
  2. {code_standards-7.0.4 → code_standards-7.1.0}/pyproject.toml +2 -2
  3. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/_meta.py +3 -0
  4. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/api.py +26 -6
  5. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/cli/main.py +78 -9
  6. code_standards-7.1.0/src/sarj_standards/configs/basedpyright.python315-watch.json +7 -0
  7. code_standards-7.1.0/src/sarj_standards/configs/basedpyright.strict.json +22 -0
  8. code_standards-7.1.0/src/sarj_standards/configs/cli-reference.v1.json +1 -0
  9. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/doctor.config.json +1 -0
  10. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.application.mjs +16 -12
  11. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.peers.json +1 -1
  12. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/eslint.strict.mjs +16 -12
  13. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/pyright.strict.json +5 -18
  14. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/ruff.application.toml +3 -0
  15. code_standards-7.1.0/src/sarj_standards/configs/ruff.python315-watch.toml +5 -0
  16. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/ruff.strict.toml +3 -0
  17. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/rule-inventory.v1.json +1 -1
  18. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/rule-ledger.json +17 -3
  19. code_standards-7.1.0/src/sarj_standards/configs/rule-warning-levels.v1.json +1 -0
  20. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/configs.py +10 -0
  21. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/doctor.py +39 -3
  22. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/scaffold.py +30 -11
  23. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/service.py +16 -1
  24. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/transaction.py +2 -0
  25. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/upgrade.py +16 -1
  26. code_standards-7.1.0/src/sarj_standards/libs/diagnostics/baseline.py +357 -0
  27. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/external.py +89 -37
  28. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/textlint.py +10 -140
  29. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/rollout.py +166 -12
  30. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/docs.py +2 -2
  31. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/repository.py +2 -0
  32. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_maintenance.py +21 -3
  33. code_standards-7.1.0/src/sarj_standards/schemas/rule-catalog.v1.json +1 -0
  34. code_standards-7.0.4/src/sarj_standards/configs/cli-reference.v1.json +0 -1
  35. code_standards-7.0.4/src/sarj_standards/configs/rule-warning-levels.v1.json +0 -1
  36. code_standards-7.0.4/src/sarj_standards/libs/diagnostics/baseline.py +0 -131
  37. code_standards-7.0.4/src/sarj_standards/schemas/rule-catalog.v1.json +0 -1
  38. {code_standards-7.0.4 → code_standards-7.1.0}/.gitignore +0 -0
  39. {code_standards-7.0.4 → code_standards-7.1.0}/LICENSE +0 -0
  40. {code_standards-7.0.4 → code_standards-7.1.0}/README.md +0 -0
  41. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/__init__.py +0 -0
  42. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/__main__.py +0 -0
  43. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/cli/__init__.py +0 -0
  44. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/markdownlint.strict.yaml +0 -0
  45. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/taplo.strict.toml +0 -0
  46. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/configs/yamllint.strict.yaml +0 -0
  47. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/__init__.py +0 -0
  48. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/__init__.py +0 -0
  49. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/exclusions.py +0 -0
  50. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/hooks.py +0 -0
  51. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/launcher.py +0 -0
  52. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/lifecycle.py +0 -0
  53. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/manifest.py +0 -0
  54. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/packagemanager.py +0 -0
  55. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/retired_suppressions.py +0 -0
  56. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/adoption/uvtool.py +0 -0
  57. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/catalogs/__init__.py +0 -0
  58. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/catalogs/slack_automations.py +0 -0
  59. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/__init__.py +0 -0
  60. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/manifest.py +0 -0
  61. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/corpus/snapshot.py +0 -0
  62. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/__init__.py +0 -0
  63. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/analysis.schema.json +0 -0
  64. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/models.py +0 -0
  65. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/serialize.py +0 -0
  66. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/diagnostics/source.py +0 -0
  67. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/filesystem.py +0 -0
  68. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/__init__.py +0 -0
  69. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/analysis.py +0 -0
  70. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/library_policy.py +0 -0
  71. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/policy.py +0 -0
  72. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/linting/runner.py +0 -0
  73. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/__init__.py +0 -0
  74. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/_values.py +0 -0
  75. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/artifacts.py +0 -0
  76. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/causality.py +0 -0
  77. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/changes.py +0 -0
  78. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/process.py +0 -0
  79. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/publish.py +0 -0
  80. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/registry.py +0 -0
  81. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/release_age.py +0 -0
  82. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/tags.py +0 -0
  83. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/release/typescript.py +0 -0
  84. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/__init__.py +0 -0
  85. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/cli_reference_artifact.py +0 -0
  86. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/comment_corpus.py +0 -0
  87. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/config_generation.py +0 -0
  88. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/hooks.py +0 -0
  89. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/ledger.py +0 -0
  90. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_authoring.py +0 -0
  91. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_catalog_artifact.py +0 -0
  92. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_changes.py +0 -0
  93. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_inventory_artifact.py +0 -0
  94. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/repository/rule_lifecycle.py +0 -0
  95. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/__init__.py +0 -0
  96. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/catalog.py +0 -0
  97. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/contracts.py +0 -0
  98. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/corpus_runner.py +0 -0
  99. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/rules/evaluation.py +0 -0
  100. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/setup/__init__.py +0 -0
  101. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/libs/setup/repository.py +0 -0
  102. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/py.typed +0 -0
  103. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/__init__.py +0 -0
  104. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/_paths.py +0 -0
  105. {code_standards-7.0.4 → code_standards-7.1.0}/src/sarj_standards/schemas/rule-catalog.v1.schema.json +0 -0
  106. {code_standards-7.0.4 → code_standards-7.1.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: 7.0.4
3
+ Version: 7.1.0
4
4
  Summary: One deterministic quality gate for Sarj Python, TypeScript, 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/
@@ -26,7 +26,7 @@ Requires-Dist: pydantic==2.13.4
26
26
  Requires-Dist: pyyaml==6.0.3
27
27
  Requires-Dist: ruff==0.16.3
28
28
  Requires-Dist: sarj-iac-lint==0.14.3
29
- Requires-Dist: sarj-python-lint==0.77.1
29
+ Requires-Dist: sarj-python-lint==0.78.0
30
30
  Requires-Dist: sarj-sql-lint==0.16.1
31
31
  Description-Content-Type: text/markdown
32
32
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "code-standards"
3
- version = "7.0.4"
3
+ version = "7.1.0"
4
4
  description = "One deterministic quality gate for Sarj Python, TypeScript, SQL, IaC, and repository policy."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -25,7 +25,7 @@ dependencies = [
25
25
  "PyYAML==6.0.3",
26
26
  "ruff==0.16.3",
27
27
  "sarj-iac-lint==0.14.3",
28
- "sarj-python-lint==0.77.1",
28
+ "sarj-python-lint==0.78.0",
29
29
  "sarj-sql-lint==0.16.1",
30
30
  ]
31
31
 
@@ -14,6 +14,9 @@ CONFIGS_DIR: Path = Path(__file__).resolve().parent / "configs"
14
14
  RUFF_STRICT: Path = CONFIGS_DIR / "ruff.strict.toml"
15
15
  RUFF_APPLICATION: Path = CONFIGS_DIR / "ruff.application.toml"
16
16
  PYRIGHT_STRICT: Path = CONFIGS_DIR / "pyright.strict.json"
17
+ BASEDPYRIGHT_STRICT: Path = CONFIGS_DIR / "basedpyright.strict.json"
18
+ RUFF_PYTHON315_WATCH: Path = CONFIGS_DIR / "ruff.python315-watch.toml"
19
+ BASEDPYRIGHT_PYTHON315_WATCH: Path = CONFIGS_DIR / "basedpyright.python315-watch.json"
17
20
  ESLINT_STRICT: Path = CONFIGS_DIR / "eslint.strict.mjs"
18
21
  ESLINT_APPLICATION: Path = CONFIGS_DIR / "eslint.application.mjs"
19
22
  MARKDOWNLINT_STRICT: Path = CONFIGS_DIR / "markdownlint.strict.yaml"
@@ -240,6 +240,7 @@ class Standards:
240
240
  mode: AnalysisMode | str = AnalysisMode.POLICY,
241
241
  rules: Sequence[str | RuleSelector] | None = None,
242
242
  staged: bool = False,
243
+ react_doctor_triggered: bool = False,
243
244
  ) -> AnalysisReport:
244
245
  try:
245
246
  normalized_trust = TrustMode(trust)
@@ -264,12 +265,18 @@ class Standards:
264
265
  try:
265
266
  baseline_counts: dict[str, int]
266
267
  baseline_counts = (
267
- diagnostic_baseline.load(self.root / adopted.diagnostic_baseline)
268
+ diagnostic_baseline.load(
269
+ self.root / adopted.diagnostic_baseline,
270
+ require_v2=True,
271
+ expected_bundle_version=__version__,
272
+ expected_catalog_digest=diagnostic_baseline.bundled_catalog_digest(),
273
+ )
268
274
  if normalized_mode is AnalysisMode.POLICY
269
275
  and adopted is not None
270
276
  and adopted.diagnostic_baseline is not None
271
277
  else {}
272
278
  )
279
+ changed_scope = diagnostic_baseline.changed_line_scope(self.root, staged=staged)
273
280
  except (OSError, TypeError, ValueError) as exc:
274
281
  return _failed_analysis(self.root, "baseline-failure", str(exc))
275
282
  try:
@@ -335,7 +342,9 @@ class Standards:
335
342
  )
336
343
  if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
337
344
  native = _with_warning_severity(native, _warning_rule_keys())
338
- return _with_coverage(_without_baselined_diagnostics(native, baseline_counts), coverage)
345
+ return _with_coverage(
346
+ _without_baselined_diagnostics(native, baseline_counts, changed_scope=changed_scope), coverage
347
+ )
339
348
  if selected_groups.typescript and adopted is not None and "eslint" not in adopted.configs:
340
349
  coverage.append(
341
350
  CoverageNotice(
@@ -355,7 +364,8 @@ class Standards:
355
364
  policy=selection_policy,
356
365
  capabilities=(frozenset({"eslint"}) if rule_selection is not None else frozenset(adopted.configs)),
357
366
  grouped=selected_groups,
358
- include_react_doctor=(paths is None or staged) and rule_selection is None,
367
+ include_react_doctor=rule_selection is None,
368
+ force_react_doctor=react_doctor_triggered,
359
369
  react_doctor_staged=staged,
360
370
  )
361
371
  if adopted is not None
@@ -364,7 +374,8 @@ class Standards:
364
374
  root=self.root,
365
375
  trust=normalized_trust,
366
376
  grouped=selected_groups,
367
- include_react_doctor=(paths is None or staged) and rule_selection is None,
377
+ include_react_doctor=rule_selection is None,
378
+ force_react_doctor=react_doctor_triggered,
368
379
  react_doctor_staged=staged,
369
380
  )
370
381
  )
@@ -386,7 +397,9 @@ class Standards:
386
397
  combined = report_from_tools(self.root, (*native.tools, *external_reports))
387
398
  if normalized_mode in {AnalysisMode.POLICY, AnalysisMode.OBSERVE}:
388
399
  combined = _with_warning_severity(combined, _warning_rule_keys())
389
- return _with_coverage(_without_baselined_diagnostics(combined, baseline_counts), coverage)
400
+ return _with_coverage(
401
+ _without_baselined_diagnostics(combined, baseline_counts, changed_scope=changed_scope), coverage
402
+ )
390
403
 
391
404
  def run(
392
405
  self,
@@ -578,7 +591,12 @@ def _failed_analysis(root: Path, kind: str, message: str) -> AnalysisReport:
578
591
  return AnalysisReport(root, Completion.FAILED, Conclusion.INCONCLUSIVE, (tool,))
579
592
 
580
593
 
581
- def _without_baselined_diagnostics(report: AnalysisReport, counts: dict[str, int]) -> AnalysisReport:
594
+ def _without_baselined_diagnostics(
595
+ report: AnalysisReport,
596
+ counts: dict[str, int],
597
+ *,
598
+ changed_scope: diagnostic_baseline.ChangedLineScope | None = None,
599
+ ) -> AnalysisReport:
582
600
  if not counts:
583
601
  return report
584
602
  remaining = counts.copy()
@@ -586,6 +604,8 @@ def _without_baselined_diagnostics(report: AnalysisReport, counts: dict[str, int
586
604
  def active(diagnostic: Diagnostic) -> bool:
587
605
  if not diagnostic_baseline.is_baselineable(diagnostic) or diagnostic.code == "SARJ206":
588
606
  return True
607
+ if diagnostic_baseline.touches_changed_lines(diagnostic, changed_scope):
608
+ return True
589
609
  fingerprint = diagnostic.fingerprint
590
610
  budget = 0 if fingerprint is None else remaining.get(fingerprint, 0)
591
611
  if budget < 1 or fingerprint is None:
@@ -50,6 +50,19 @@ _INVALID_DOCTOR_IDS = frozenset(
50
50
  "doctor.package-json.invalid",
51
51
  }
52
52
  )
53
+ _REACT_DOCTOR_METADATA = frozenset(
54
+ {
55
+ "doctor.config.json",
56
+ "eslint.config.js",
57
+ "eslint.config.mjs",
58
+ "package-lock.json",
59
+ "package.json",
60
+ "pnpm-lock.yaml",
61
+ "tsconfig.json",
62
+ "yarn.lock",
63
+ }
64
+ )
65
+ _REACT_DOCTOR_TYPESCRIPT_SUFFIXES = frozenset({".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts"})
53
66
 
54
67
 
55
68
  class _EvaluationScope(StrEnum):
@@ -125,6 +138,8 @@ class _Args(argparse.Namespace):
125
138
  selector: RuleSelector | None = None
126
139
  evaluation_scope: _EvaluationScope = _EvaluationScope.CORPUS
127
140
  baseline: Path | None = None
141
+ baseline_rules: list[str]
142
+ react_doctor_triggered: bool = False
128
143
  package: list[str]
129
144
  exclude_subtree: list[str]
130
145
  allow_increase: bool = False
@@ -141,6 +156,7 @@ class _Args(argparse.Namespace):
141
156
  self.repo_only = []
142
157
  self.roots = []
143
158
  self.release_exclude = []
159
+ self.baseline_rules = []
144
160
  self.release_exclude_file = []
145
161
  self.release_targets = []
146
162
  self.wheels = []
@@ -770,7 +786,7 @@ def cmd_library_policy(args: _Args, *, selected_paths: Iterable[str] | None = No
770
786
  return 1 if findings else 0
771
787
 
772
788
 
773
- def cmd_check(args: _Args) -> int:
789
+ def cmd_check(args: _Args) -> int: # ruff: ignore[too-many-locals] -- staged and PR scopes retain Doctor triggers.
774
790
  from sarj_standards.libs.linting import external, runner # ruff: ignore[import-outside-top-level]
775
791
 
776
792
  root = _resolve_dest(args.dest)
@@ -779,9 +795,11 @@ def cmd_check(args: _Args) -> int:
779
795
  return catalog_status
780
796
  repository_wide = not args.files
781
797
  pull_request_scoped = False
798
+ react_doctor_triggered = False
782
799
  if args.staged:
783
800
  try:
784
801
  staged_names = _staged_file_names(root)
802
+ react_doctor_triggered = _react_doctor_triggered_by(staged_names)
785
803
  staged = _safe_staged_paths(root, staged_names)
786
804
  except (OSError, subprocess.SubprocessError) as exc:
787
805
  if args.output_format != "text":
@@ -819,7 +837,11 @@ def cmd_check(args: _Args) -> int:
819
837
  pull_request_scoped = True
820
838
  elif (root / ".git").exists() and (base := external.change_scope_base()):
821
839
  try:
822
- args.files = [path for path in _changed_file_paths(root, base) if runner.accepts_hook_path(Path(path))]
840
+ changed_names = _changed_file_names(root, base)
841
+ react_doctor_triggered = _react_doctor_triggered_by(changed_names)
842
+ args.files = [
843
+ path for path in _safe_staged_paths(root, changed_names) if runner.accepts_hook_path(Path(path))
844
+ ]
823
845
  pull_request_scoped = True
824
846
  except (OSError, subprocess.SubprocessError) as exc:
825
847
  if args.output_format != "text":
@@ -838,7 +860,7 @@ def cmd_check(args: _Args) -> int:
838
860
  if health_status:
839
861
  return health_status
840
862
  args.files = [path for path in args.files if runner.accepts_hook_path(Path(path))]
841
- if not args.files:
863
+ if not args.files and not react_doctor_triggered:
842
864
  return 0
843
865
  if args.output_format != "text":
844
866
  if _validate_analysis_output(args, root):
@@ -862,18 +884,33 @@ def cmd_check(args: _Args) -> int:
862
884
  external=True,
863
885
  trust=TrustMode.TRUSTED if args.trust_repository_code else TrustMode.SAFE,
864
886
  mode=AnalysisMode.POLICY,
887
+ react_doctor_triggered=react_doctor_triggered,
865
888
  )
866
889
  return _emit_analysis_report(args, root, report)
890
+ args.react_doctor_triggered = react_doctor_triggered
867
891
  return cmd_analyze(args)
868
892
  if pull_request_scoped:
869
893
  adoption_report = _machine_adoption_gate(root)
870
894
  if adoption_report is not None:
871
895
  return _emit_analysis_report(args, root, adoption_report)
872
896
  if not args.files:
897
+ if react_doctor_triggered:
898
+ return _run_canonical_check(
899
+ root,
900
+ (),
901
+ trusted=args.trust_repository_code,
902
+ react_doctor_triggered=True,
903
+ )
873
904
  return _run_canonical_check(root, (), trusted=args.trust_repository_code)
874
905
  if not args.files:
875
906
  return cmd_verify(args)
876
- return _run_canonical_check(root, list(args.files), trusted=args.trust_repository_code, staged=args.staged)
907
+ check_options: dict[str, bool] = {
908
+ "trusted": args.trust_repository_code,
909
+ "staged": args.staged,
910
+ }
911
+ if react_doctor_triggered:
912
+ check_options["react_doctor_triggered"] = True
913
+ return _run_canonical_check(root, list(args.files), **check_options)
877
914
 
878
915
 
879
916
  def cmd_validate_slack_automations(args: _Args) -> int:
@@ -945,6 +982,7 @@ def _run_canonical_check(
945
982
  raw: bool = False,
946
983
  trusted: bool = False,
947
984
  staged: bool = False,
985
+ react_doctor_triggered: bool = False,
948
986
  ) -> int:
949
987
  from sarj_standards.api import AnalysisMode, Standards, TrustMode # ruff: ignore[import-outside-top-level]
950
988
  from sarj_standards.libs.diagnostics import to_text # ruff: ignore[import-outside-top-level]
@@ -955,6 +993,7 @@ def _run_canonical_check(
955
993
  trust=TrustMode.TRUSTED if trusted else TrustMode.SAFE,
956
994
  mode=AnalysisMode.RAW if raw else AnalysisMode.POLICY,
957
995
  staged=staged,
996
+ react_doctor_triggered=react_doctor_triggered,
958
997
  )
959
998
  rendered = to_text(report)
960
999
  if rendered:
@@ -977,6 +1016,7 @@ def cmd_analyze(args: _Args) -> int:
977
1016
  trust=args.trust,
978
1017
  mode=AnalysisMode(args.analysis_mode),
979
1018
  staged=args.staged,
1019
+ react_doctor_triggered=args.react_doctor_triggered,
980
1020
  )
981
1021
  return _emit_analysis_report(args, root, report)
982
1022
 
@@ -1362,7 +1402,7 @@ def _staged_file_names(root: Path) -> list[str]:
1362
1402
  msg = "git is required for --staged"
1363
1403
  raise OSError(msg)
1364
1404
  completed = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed argv, no shell.
1365
- [git, "diff", "--cached", "--name-only", "--diff-filter=ACMR", "-z"],
1405
+ [git, "diff", "--cached", "--name-only", "--diff-filter=ACDMR", "-z"],
1366
1406
  cwd=root,
1367
1407
  check=True,
1368
1408
  capture_output=True,
@@ -1373,19 +1413,29 @@ def _staged_file_names(root: Path) -> list[str]:
1373
1413
 
1374
1414
 
1375
1415
  def _changed_file_paths(root: Path, base: str) -> list[str]:
1416
+ return _safe_staged_paths(root, _changed_file_names(root, base))
1417
+
1418
+
1419
+ def _changed_file_names(root: Path, base: str) -> list[str]:
1376
1420
  git = shutil.which("git")
1377
1421
  if git is None:
1378
1422
  msg = "git is required for pull-request change scoping"
1379
1423
  raise OSError(msg)
1380
1424
  completed = subprocess.run( # ruff: ignore[subprocess-without-shell-equals-true] -- fixed argv, no shell.
1381
- [git, "diff", "--name-only", "--diff-filter=ACMR", "-z", f"{base}...HEAD", "--"],
1425
+ [git, "diff", "--name-only", "--diff-filter=ACDMR", "-z", f"{base}...HEAD", "--"],
1382
1426
  cwd=root,
1383
1427
  check=True,
1384
1428
  capture_output=True,
1385
1429
  env=_git_environment(),
1386
1430
  )
1387
- names = [part.decode("utf-8", errors="surrogateescape") for part in completed.stdout.split(b"\0") if part]
1388
- return _safe_staged_paths(root, names)
1431
+ return [part.decode("utf-8", errors="surrogateescape") for part in completed.stdout.split(b"\0") if part]
1432
+
1433
+
1434
+ def _react_doctor_triggered_by(paths: Iterable[str]) -> bool:
1435
+ return any(
1436
+ Path(value).name in _REACT_DOCTOR_METADATA or Path(value).suffix.lower() in _REACT_DOCTOR_TYPESCRIPT_SUFFIXES
1437
+ for value in paths
1438
+ )
1389
1439
 
1390
1440
 
1391
1441
  def _safe_staged_paths(root: Path, paths: Iterable[str]) -> list[str]:
@@ -1650,7 +1700,18 @@ def cmd_baseline(args: _Args) -> int:
1650
1700
  print(f"error: {issue.kind}: {issue.message}", file=sys.stderr)
1651
1701
  return 2
1652
1702
  eligible = tuple(item for item in report.diagnostics if baseline.is_baselineable(item))
1653
- rendered = baseline.render(eligible)
1703
+ provenance = {
1704
+ "bundle_version": __version__,
1705
+ "consumer_base_sha": baseline.repository_base_sha(root),
1706
+ "catalog_digest": baseline.bundled_catalog_digest(),
1707
+ }
1708
+ if args.baseline_cmd == "update" and args.baseline_rules:
1709
+ if not output.is_file():
1710
+ print(f"error: scoped diagnostic baseline update requires an existing baseline: {output}", file=sys.stderr)
1711
+ return 2
1712
+ rendered = baseline.merge_scoped(output, eligible, selectors=args.baseline_rules, **provenance)
1713
+ else:
1714
+ rendered = baseline.render(eligible, **provenance)
1654
1715
  try:
1655
1716
  output.parent.mkdir(parents=True, exist_ok=True)
1656
1717
  output.write_text(rendered, encoding="utf-8")
@@ -1916,6 +1977,14 @@ def build_parser() -> argparse.ArgumentParser: # ruff: ignore[too-many-locals]
1916
1977
  action="store_true",
1917
1978
  help="run repository-local analyzers that execute project code",
1918
1979
  )
1980
+ if name == "update":
1981
+ command.add_argument(
1982
+ "--rule",
1983
+ action="append",
1984
+ dest="baseline_rules",
1985
+ default=[],
1986
+ help="replace debt only for this newly promoted rule (repeatable; source:RULE is also accepted)",
1987
+ )
1919
1988
  command.add_argument("files", nargs="*", help="paths to analyze (default: the whole repository)")
1920
1989
 
1921
1990
  ratchet = sub.add_parser("ratchet", help="keep the Python suppression budget from growing")
@@ -0,0 +1,7 @@
1
+ {
2
+ // Advisory compatibility profile. Experimental diagnostics stay isolated
3
+ // here and never leak into the blocking Python 3.14 policy.
4
+ "extends": "./basedpyright.strict.json",
5
+ "pythonVersion": "3.15",
6
+ "enableExperimentalFeatures": true
7
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ // Additive active BasedPyright policy. Upstream-Pyright consumers can extend
3
+ // pyright.strict.json directly without receiving unrecognized settings.
4
+ "extends": "./pyright.strict.json",
5
+ "enableBasedFeatures": false,
6
+ "strictGenericNarrowing": true,
7
+
8
+ "reportInvalidCast": "error",
9
+ "reportUnsafeMultipleInheritance": "error",
10
+ "reportImplicitRelativeImport": "error",
11
+ "reportExplicitAny": "error",
12
+ "reportIgnoreCommentWithoutRule": "error",
13
+ "reportPrivateLocalImportUsage": "error",
14
+ "reportAny": "error",
15
+ "reportUnannotatedClassAttribute": "error",
16
+
17
+ "reportImplicitAbstractClass": "error",
18
+ "reportEmptyAbstractUsage": "error",
19
+ "reportIncompatibleUnannotatedOverride": "error",
20
+ "reportInvalidAbstractMethod": "error",
21
+ "reportSelfClsDefault": "error"
22
+ }
@@ -0,0 +1 @@
1
+ {"commands":[{"commands":[],"name":"doctor","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["text","json"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":"output format (default: text)"},{"choices":[],"kind":"option","metavar":null,"names":["--repair"],"repeatable":false,"required":false,"summary":"transactionally repair safe drift with the executing bundle, then re-diagnose"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"with --repair, update configuration without installing dependencies or hooks"}],"path":["doctor"],"summary":"diagnose adoption health and optionally repair safe drift","usage":"code-standards doctor [-h] [--format OUTPUT_FORMAT] [--repair] [--no-install]"},{"commands":[],"name":"setup","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["pre-commit","lefthook","none"],"kind":"option","metavar":"HOOKS","names":["--hooks"],"repeatable":false,"required":false,"summary":"hook manager (default: detect Lefthook, otherwise pre-commit)"},{"choices":[],"kind":"option","metavar":"PYTHON_DEST","names":["--python-dest"],"repeatable":false,"required":false,"summary":"the directory that owns pyproject.toml (default: detected)"},{"choices":[],"kind":"option","metavar":"TYPESCRIPT_DEST","names":["--typescript-dest"],"repeatable":false,"required":false,"summary":"the directory that owns the npm lockfile (default: detected)"},{"choices":[],"kind":"option","metavar":null,"names":["--dry-run"],"repeatable":false,"required":false,"summary":"print the complete plan without writing"},{"choices":[],"kind":"option","metavar":null,"names":["--force"],"repeatable":false,"required":false,"summary":"replace conflicting generated lint configuration after review"},{"choices":["standard","application"],"kind":"option","metavar":"PROFILE","names":["--profile"],"repeatable":false,"required":false,"summary":"policy profile to adopt (default: existing value, otherwise standard)"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"write wiring without installing dependencies or hooks"},{"choices":["eslint","markdownlint","pyright","ruff","taplo","yamllint"],"kind":"option","metavar":"ONLY","names":["--config"],"repeatable":true,"required":false,"summary":"select one config explicitly (repeatable)"}],"path":["setup"],"summary":"adopt or converge the repository in one idempotent operation","usage":"code-standards setup [-h] [--hooks HOOKS] [--python-dest PYTHON_DEST] [--typescript-dest TYPESCRIPT_DEST] [--dry-run] [--force] [--profile PROFILE] [--no-install] [--config ONLY ...]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow executable repository ESLint configuration (generated hooks and CI set this explicitly)"},{"choices":[],"kind":"option","metavar":null,"names":["--staged"],"repeatable":false,"required":false,"summary":"run custom rules on hook-supplied paths, or discover staged files when none are supplied"},{"choices":["text","json","sarif","github"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"write JSON or SARIF atomically to PATH"},{"choices":["0","1","2","3","4","5","6","7","8","9","10"],"kind":"option","metavar":"MAX_ANNOTATIONS_PER_LEVEL","names":["--max-annotations-per-level"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; when omitted, check the complete repository"}],"path":["check"],"summary":"run the complete quality gate or check selected paths","usage":"code-standards check [-h] [--trust-repository-code] [--staged] [--format OUTPUT_FORMAT] [--output OUTPUT] [--max-annotations-per-level MAX_ANNOTATIONS_PER_LEVEL] [files ...]"},{"commands":[],"name":"validate-slack-automations","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"PATH","names":["slack_catalog"],"repeatable":false,"required":true,"summary":""}],"path":["validate-slack-automations"],"summary":"validate a versioned Slack automation catalog","usage":"code-standards validate-slack-automations [-h] PATH"},{"commands":[],"name":"observe","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"SELECTED_RULES","names":["--rule"],"repeatable":true,"required":true,"summary":"canonical ENGINE:ID selector (repeatable)"},{"choices":["text","json","sarif","github"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow repository ESLint configuration to execute"},{"choices":[],"kind":"option","metavar":"MAX_ANNOTATIONS_PER_LEVEL","names":["--max-annotations-per-level"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; defaults to adopted verification paths"}],"path":["observe"],"summary":"report warning-stage findings with exit 0; invalid input or execution still exits 2","usage":"code-standards observe [-h] --rule SELECTED_RULES ... [--format OUTPUT_FORMAT] [--output OUTPUT] [--trust-repository-code] [--max-annotations-per-level MAX_ANNOTATIONS_PER_LEVEL] [files ...]"},{"commands":[],"name":"fix","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--staged"],"repeatable":false,"required":false,"summary":"fix only files staged in Git"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"selected paths; when omitted, fix the complete repository"}],"path":["fix"],"summary":"apply safe formatting and lint fixes","usage":"code-standards fix [-h] [--staged] [files ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"preview without writing; exit 1 when changes exist"},{"choices":[],"kind":"option","metavar":null,"names":["--offline"],"repeatable":false,"required":false,"summary":"reconverge the executing bundle and skip every network-dependent install; does not resolve latest"},{"choices":[],"kind":"option","metavar":"VERSION","names":["--to"],"repeatable":false,"required":false,"summary":"resolve and apply exactly this immutable coherent bundle version"},{"choices":[],"kind":"option","metavar":null,"names":["--no-install"],"repeatable":false,"required":false,"summary":"do not install dependencies or hooks"}],"path":["update"],"summary":"upgrade to the latest published coherent Standards bundle","usage":"code-standards update [-h] [--check] [--offline] [--to VERSION] [--no-install]"},{"commands":[{"commands":[],"name":"init","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"baseline JSON (default: diagnostic-baseline.json)"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"run repository-local analyzers that execute project code"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"paths to analyze (default: the whole repository)"}],"path":["baseline","init"],"summary":"record the first diagnostic baseline","usage":"code-standards baseline init [-h] [--output OUTPUT] [--trust-repository-code] [files ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"baseline JSON (default: diagnostic-baseline.json)"},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"run repository-local analyzers that execute project code"},{"choices":[],"kind":"option","metavar":"BASELINE_RULES","names":["--rule"],"repeatable":true,"required":false,"summary":"replace debt only for this newly promoted rule (repeatable; source:RULE is also accepted)"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":"paths to analyze (default: the whole repository)"}],"path":["baseline","update"],"summary":"re-record the diagnostic baseline after reviewed cleanup","usage":"code-standards baseline update [-h] [--output OUTPUT] [--trust-repository-code] [--rule BASELINE_RULES ...] [files ...]"}],"name":"baseline","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["baseline"],"summary":"grandfather today's findings so only new ones fail","usage":"code-standards baseline [-h] {init,update}"},{"commands":[{"commands":[],"name":"init","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","init"],"summary":"create the first suppression budget","usage":"code-standards ratchet init [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","check"],"summary":"fail when suppression debt grows","usage":"code-standards ratchet check [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"status","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"}],"path":["ratchet","status"],"summary":"show current suppression debt and available reductions","usage":"code-standards ratchet status [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...]"},{"commands":[],"name":"update","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BASELINE","names":["--baseline"],"repeatable":false,"required":false,"summary":"budget JSON (default: suppression-baseline.json)"},{"choices":[],"kind":"option","metavar":"PACKAGE","names":["--package"],"repeatable":true,"required":false,"summary":"Python package root (repeatable)"},{"choices":[],"kind":"option","metavar":"EXCLUDE_SUBTREE","names":["--exclude-subtree"],"repeatable":true,"required":false,"summary":"generated or vendored subtree to persistently exclude (repeatable)"},{"choices":[],"kind":"option","metavar":null,"names":["--allow-increase"],"repeatable":false,"required":false,"summary":"permit a reviewed increase in suppression debt"}],"path":["ratchet","update"],"summary":"lock in reviewed suppression-budget changes","usage":"code-standards ratchet update [-h] [--baseline BASELINE] [--package PACKAGE ...] [--exclude-subtree EXCLUDE_SUBTREE ...] [--allow-increase]"}],"name":"ratchet","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["ratchet"],"summary":"keep the Python suppression budget from growing","usage":"code-standards ratchet [-h] {init,check,status,update}"},{"commands":[{"commands":[],"name":"list","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["exclude","list"],"summary":"list the complete denylist","usage":"code-standards exclude list [-h]"},{"commands":[],"name":"add","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["path","rule"],"kind":"positional","metavar":"{path,rule}","names":["exclude_kind"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"positional","metavar":"value","names":["value"],"repeatable":false,"required":true,"summary":"repository-relative glob or canonical engine:rule selector"}],"path":["exclude","add"],"summary":"add one exact denylist entry","usage":"code-standards exclude add [-h] {path,rule} value"},{"commands":[],"name":"remove","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["path","rule"],"kind":"positional","metavar":"{path,rule}","names":["exclude_kind"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"positional","metavar":"value","names":["value"],"repeatable":false,"required":true,"summary":"repository-relative glob or canonical engine:rule selector"}],"path":["exclude","remove"],"summary":"remove one exact denylist entry","usage":"code-standards exclude remove [-h] {path,rule} value"}],"name":"exclude","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["exclude"],"summary":"inspect or change explicit path and rule exclusions","usage":"code-standards exclude [-h] {list,add,remove}"},{"commands":[{"commands":[],"name":"state","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","state"],"summary":"print detected adoption state as JSON","usage":"code-standards show state [-h]"},{"commands":[],"name":"configs","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","configs"],"summary":"list bundled configurations","usage":"code-standards show configs [-h]"},{"commands":[],"name":"config","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["eslint","markdownlint","pyright","ruff","taplo","yamllint"],"kind":"positional","metavar":"name","names":["name"],"repeatable":false,"required":true,"summary":""},{"choices":["standard","application"],"kind":"option","metavar":"PROFILE","names":["--profile"],"repeatable":false,"required":false,"summary":""}],"path":["show","config"],"summary":"print one bundled configuration path","usage":"code-standards show config [-h] name [--profile PROFILE]"},{"commands":[],"name":"peers","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","peers"],"summary":"show tested ESLint peer dependencies and install command","usage":"code-standards show peers [-h]"},{"commands":[],"name":"rules","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show","rules"],"summary":"print the machine-readable custom-rule inventory","usage":"code-standards show rules [-h]"},{"commands":[],"name":"ci","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"write a managed workflow inside the repository"}],"path":["show","ci"],"summary":"print a complete pinned GitHub Actions standards workflow","usage":"code-standards show ci [-h] [--output OUTPUT]"}],"name":"show","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["show"],"summary":"print read-only package and adoption information","usage":"code-standards show [-h] {state,configs,config,peers,rules,ci}"},{"commands":[{"commands":[],"name":"setup","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"print the deterministic setup plan without executing it"}],"path":["maintain","setup"],"summary":"install every standards development environment and repository hook","usage":"code-standards maintain setup [-h] [--check]"},{"commands":[{"commands":[],"name":"check-tag","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"tag","names":["tag"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","check-tag"],"summary":"require a release tag to match its package manifest","usage":"code-standards maintain release check-tag [-h] tag"},{"commands":[],"name":"verify-tags","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"RELEASE_COMMIT","names":["--commit"],"repeatable":false,"required":false,"summary":"also require existing tags to match this publishing commit or an unchanged package tree"}],"path":["maintain","release","verify-tags"],"summary":"verify all manifest release tags on origin","usage":"code-standards maintain release verify-tags [-h] [--commit RELEASE_COMMIT]"},{"commands":[],"name":"create-tags","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["typescript","bootstrap","python","sql","iac","standards","tsconfig","docs-ui"],"kind":"positional","metavar":"release_targets","names":["release_targets"],"repeatable":true,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_COMMIT","names":["--commit"],"repeatable":false,"required":true,"summary":"exact commit that was published"},{"choices":[],"kind":"option","metavar":"ATTEMPTS","names":["--attempts"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"DELAY_SECONDS","names":["--delay-seconds"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","release","create-tags"],"summary":"create and push manifest release tags","usage":"code-standards maintain release create-tags [-h] release_targets ... --commit RELEASE_COMMIT [--attempts ATTEMPTS] [--delay-seconds DELAY_SECONDS]"},{"commands":[],"name":"changes","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"GITHUB_OUTPUT","names":["--github-output"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","changes"],"summary":"emit package version changes between Git revisions","usage":"code-standards maintain release changes [-h] --before BEFORE --after AFTER --github-output GITHUB_OUTPUT"},{"commands":[],"name":"causality","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","causality"],"summary":"require every publishable package change to bump its version","usage":"code-standards maintain release causality [-h] --before BEFORE --after AFTER"},{"commands":[],"name":"lock-age","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"lockfile","names":["lockfile"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"MINIMUM_AGE","names":["--minimum-days"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_EXCLUDE","names":["--exclude"],"repeatable":true,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"RELEASE_EXCLUDE_FILE","names":["--exclude-file"],"repeatable":true,"required":false,"summary":"line-oriented exact package@version exceptions (repeatable)"}],"path":["maintain","release","lock-age"],"summary":"enforce npm lockfile minimum release age","usage":"code-standards maintain release lock-age [-h] lockfile [--minimum-days MINIMUM_AGE] [--exclude RELEASE_EXCLUDE ...] [--exclude-file RELEASE_EXCLUDE_FILE ...]"},{"commands":[],"name":"typescript","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["check","pack","publish"],"kind":"positional","metavar":"release_mode","names":["release_mode"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":"artifact directory (required for pack)"}],"path":["maintain","release","typescript"],"summary":"check, pack, or publish the TypeScript package","usage":"code-standards maintain release typescript [-h] release_mode [--output OUTPUT]"},{"commands":[],"name":"verify-wheel","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"wheels","names":["wheels"],"repeatable":true,"required":true,"summary":""}],"path":["maintain","release","verify-wheel"],"summary":"require non-empty license text in built Python wheels","usage":"code-standards maintain release verify-wheel [-h] wheels ..."},{"commands":[],"name":"verify-publications","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"ATTEMPTS","names":["--attempts"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"DELAY_SECONDS","names":["--delay-seconds"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","release","verify-publications"],"summary":"wait for every exact sibling publication required by Standards","usage":"code-standards maintain release verify-publications [-h] [--attempts ATTEMPTS] [--delay-seconds DELAY_SECONDS]"},{"commands":[],"name":"publish","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["typescript","bootstrap","python","sql","iac","standards","tsconfig","docs-ui"],"kind":"positional","metavar":"release_target","names":["release_target"],"repeatable":false,"required":true,"summary":""}],"path":["maintain","release","publish"],"summary":"build and publish one package through its native client","usage":"code-standards maintain release publish [-h] release_target"}],"name":"release","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","release"],"summary":"validate and build publishable release artifacts","usage":"code-standards maintain release [-h] {check-tag,verify-tags,create-tags,changes,causality,lock-age,typescript,verify-wheel,verify-publications,publish}"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":["ci-history","file-conventions","private-refs","versions"],"kind":"option","metavar":"REPO_ONLY","names":["--only"],"repeatable":true,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"COMMITS","names":["--commits"],"repeatable":false,"required":false,"summary":"also inspect commit messages in this revision range"},{"choices":[],"kind":"option","metavar":"POLICY_DEST","names":["--policy-root"],"repeatable":false,"required":false,"summary":"trusted repository policy root (default: --root)"},{"choices":[],"kind":"option","metavar":"PRIVATE_REFS_FILE","names":["--private-refs-file"],"repeatable":false,"required":false,"summary":"private-reference TOML outside the scanned repository"},{"choices":[],"kind":"option","metavar":null,"names":["--quiet"],"repeatable":false,"required":false,"summary":"hide finding details"}],"path":["maintain","check"],"summary":"run repository policy gates","usage":"code-standards maintain check [-h] [--only REPO_ONLY ...] [--commits COMMITS] [--policy-root POLICY_DEST] [--private-refs-file PRIVATE_REFS_FILE] [--quiet]"},{"commands":[],"name":"sync-ledger","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report drift without writing"}],"path":["maintain","sync-ledger"],"summary":"synchronize the rule compatibility ledger","usage":"code-standards maintain sync-ledger [-h] [--check]"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs","check"],"summary":"","usage":"code-standards maintain docs check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs","sync"],"summary":"","usage":"code-standards maintain docs sync [-h]"}],"name":"docs","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","docs"],"summary":"check or synchronize source-derived documentation","usage":"code-standards maintain docs [-h] {check,sync}"},{"commands":[],"name":"comment-corpus","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"roots","names":["roots"],"repeatable":true,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"PRIVATE_JSONL","names":["--include-text"],"repeatable":false,"required":false,"summary":"write sensitive comment text to a new owner-readable file"}],"path":["maintain","comment-corpus"],"summary":"extract comments for calibration","usage":"code-standards maintain comment-corpus [-h] roots ... [--include-text PRIVATE_JSONL]"},{"commands":[{"commands":[],"name":"install","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","hooks","install"],"summary":"install Lefthook","usage":"code-standards maintain hooks install [-h]"}],"name":"hooks","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","hooks"],"summary":"manage the pinned repository hooks","usage":"code-standards maintain hooks [-h] {install}"},{"commands":[{"commands":[],"name":"manifest","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","manifest"],"summary":"print the shipped rule inventory","usage":"code-standards maintain rules manifest [-h]"},{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","check"],"summary":"verify the shipped rule inventory matches live registries","usage":"code-standards maintain rules check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules","sync"],"summary":"update the shipped rule inventory from live registries","usage":"code-standards maintain rules sync [-h]"},{"commands":[],"name":"new","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":["architecture","correctness","maintainability","performance","security","style","testing"],"kind":"option","metavar":"RULE_CATEGORY","names":["--category"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"RULE_SUMMARY","names":["--summary"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--apply"],"repeatable":false,"required":false,"summary":"create the planned files"}],"path":["maintain","rules","new"],"summary":"plan or create author-owned rule and test skeletons","usage":"code-standards maintain rules new [-h] selector --category RULE_CATEGORY --summary RULE_SUMMARY [--apply]"},{"commands":[],"name":"stage-warning","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report required staging without writing"}],"path":["maintain","rules","stage-warning"],"summary":"prepare one registered rule for warning-first publication","usage":"code-standards maintain rules stage-warning [-h] selector [--check]"},{"commands":[],"name":"prepare","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"},{"choices":[],"kind":"option","metavar":null,"names":["--check"],"repeatable":false,"required":false,"summary":"report required preparation without writing"}],"path":["maintain","rules","prepare"],"summary":"validate and prepare one registered rule for warning-first publication","usage":"code-standards maintain rules prepare [-h] selector [--check]"},{"commands":[],"name":"verify","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"positional","metavar":"selector","names":["selector"],"repeatable":false,"required":true,"summary":"canonical ENGINE:ID selector"}],"path":["maintain","rules","verify"],"summary":"validate one registered rule's authored files and public examples","usage":"code-standards maintain rules verify [-h] selector"},{"commands":[],"name":"changes","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"BEFORE","names":["--before"],"repeatable":false,"required":true,"summary":""},{"choices":[],"kind":"option","metavar":"AFTER","names":["--after"],"repeatable":false,"required":true,"summary":""},{"choices":["json","text"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""}],"path":["maintain","rules","changes"],"summary":"compare rule inventory and policy between two Git revisions","usage":"code-standards maintain rules changes [-h] --before BEFORE --after AFTER [--format OUTPUT_FORMAT]"},{"commands":[],"name":"evaluate","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":"SELECTED_RULES","names":["--rule"],"repeatable":true,"required":true,"summary":"canonical ENGINE:ID selector (repeatable)"},{"choices":["corpus","effective"],"kind":"option","metavar":"EVALUATION_SCOPE","names":["--scope"],"repeatable":false,"required":false,"summary":"corpus ignores baselines/rule exclusions; effective applies adopted repository policy"},{"choices":["json","text"],"kind":"option","metavar":"OUTPUT_FORMAT","names":["--format"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":"OUTPUT","names":["--output"],"repeatable":false,"required":false,"summary":""},{"choices":[],"kind":"option","metavar":null,"names":["--trust-repository-code"],"repeatable":false,"required":false,"summary":"allow executable repository ESLint configuration"},{"choices":[],"kind":"positional","metavar":"files","names":["files"],"repeatable":true,"required":false,"summary":""}],"path":["maintain","rules","evaluate"],"summary":"calibrate selected custom rules; findings exit 1 and invalid input or execution exits 2","usage":"code-standards maintain rules evaluate [-h] --rule SELECTED_RULES ... [--scope EVALUATION_SCOPE] [--format OUTPUT_FORMAT] [--output OUTPUT] [--trust-repository-code] [files ...]"}],"name":"rules","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","rules"],"summary":"inspect live custom rules","usage":"code-standards maintain rules [-h] {manifest,check,sync,new,stage-warning,prepare,verify,changes,evaluate}"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog","check"],"summary":"verify the public catalog matches every live rule","usage":"code-standards maintain catalog check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog","sync"],"summary":"update the public catalog from source-owned rule metadata","usage":"code-standards maintain catalog sync [-h]"}],"name":"catalog","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","catalog"],"summary":"maintain the source-derived public rule catalog","usage":"code-standards maintain catalog [-h] {check,sync}"},{"commands":[{"commands":[],"name":"check","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference","check"],"summary":"verify the shipped reference matches the parser graph","usage":"code-standards maintain cli-reference check [-h]"},{"commands":[],"name":"sync","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference","sync"],"summary":"update the shipped reference from the parser graph","usage":"code-standards maintain cli-reference sync [-h]"}],"name":"cli-reference","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain","cli-reference"],"summary":"maintain the source-derived CLI reference","usage":"code-standards maintain cli-reference [-h] {check,sync}"}],"name":"maintain","options":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"}],"path":["maintain"],"summary":"repository policy, hooks, rule ledgers, and releases","usage":"code-standards maintain [-h] {setup,release,check,sync-ledger,docs,comment-corpus,hooks,rules,catalog,cli-reference}"}],"epilog":"Start with `code-standards setup`, then use `code-standards check`.","globalOptions":[{"choices":[],"kind":"option","metavar":null,"names":["-h","--help"],"repeatable":false,"required":false,"summary":"show this help message and exit"},{"choices":[],"kind":"option","metavar":null,"names":["--version"],"repeatable":false,"required":false,"summary":"show program's version number and exit"},{"choices":[],"kind":"option","metavar":"DEST","names":["--root"],"repeatable":false,"required":false,"summary":"repository root shared by the selected command (default: current directory)"}],"launcher":{"install":"uv tool install --python 3.14 code-standards","runLatest":"uvx --no-config --isolated --python 3.14 --from code-standards code-standards"},"program":"code-standards","schemaVersion":1,"summary":"Adopt, check, fix, diagnose, and update sarj-ai standards (v7.1.0).","version":"7.1.0"}
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "serverAuthFunctionNames": ["forRequest"],
18
18
  "share": false,
19
+ "warnings": false,
19
20
  "supplyChain": {
20
21
  "enabled": false
21
22
  }
@@ -282,7 +282,9 @@ const UNICORN_MODERNISATION_RULES = {
282
282
  "unicorn/prefer-import-meta-properties": "error",
283
283
  "unicorn/prefer-iterable-in-constructor": "error",
284
284
  "unicorn/prefer-iterator-concat": "error",
285
+ "unicorn/prefer-iterator-helpers": "error",
285
286
  "unicorn/prefer-iterator-to-array": "error",
287
+ "unicorn/prefer-iterator-to-array-at-end": "error",
286
288
  "unicorn/prefer-map-from-entries": "error",
287
289
  "unicorn/prefer-math-abs": "error",
288
290
  "unicorn/prefer-math-constants": "error",
@@ -747,6 +749,8 @@ export function createConfig(options = {}) {
747
749
  // schema changes. Requiring an identical shape keeps the diagnostic tied
748
750
  // to structural evidence instead of name correlation.
749
751
  "@sarj/prefer-zod-infer": "error",
752
+ "@sarj/interface-contract-members-private": "error",
753
+ "@sarj/prefer-ecmascript-private-members": "error",
750
754
 
751
755
  // Maintained upstream rules own these concerns instead of local copies.
752
756
  // `.nullable().optional()` is exactly `.nullish()`, so prefer-nullish
@@ -943,12 +947,12 @@ export function createConfig(options = {}) {
943
947
  "@sarj/no-raw-env": "error",
944
948
  "@sarj/no-sentinel-return-on-catch": "error",
945
949
  "@sarj/no-log-only-catch": "error",
946
- "@sarj/no-bare-return-from-test-catch": "warn",
947
- "@sarj/no-dangerously-allow-svg": "warn",
948
- "@sarj/no-duplicate-lifecycle-refresh-listeners": "warn",
949
- "@sarj/no-production-browser-source-maps": "warn",
950
- "@sarj/no-router-refresh-polling": "warn",
951
- "@sarj/no-server-env-in-client-component": "warn",
950
+ "@sarj/no-bare-return-from-test-catch": "error",
951
+ "@sarj/no-dangerously-allow-svg": "error",
952
+ "@sarj/no-duplicate-lifecycle-refresh-listeners": "error",
953
+ "@sarj/no-production-browser-source-maps": "error",
954
+ "@sarj/no-router-refresh-polling": "error",
955
+ "@sarj/no-server-env-in-client-component": "error",
952
956
  "@sarj/no-long-comment": "error",
953
957
  "@sarj/no-vague-suppression-description": "error",
954
958
  "@sarj/no-generic-single-export-module": "error",
@@ -984,11 +988,11 @@ export function createConfig(options = {}) {
984
988
  "@sarj/prefer-non-nullable-collection": "error",
985
989
  "@sarj/prefer-await-in-async-return": "error",
986
990
  "@sarj/no-sleep-in-test-body": "error",
987
- "@sarj/iac-source-coupled-test": "warn",
988
- "@sarj/repeated-static-call-cases": "warn",
989
- "@sarj/require-use-form-default-values": "warn",
990
- "@sarj/require-use-server-in-actions-file": "warn",
991
- "@sarj/source-coupled-test": "warn",
991
+ "@sarj/iac-source-coupled-test": "error",
992
+ "@sarj/repeated-static-call-cases": "error",
993
+ "@sarj/require-use-form-default-values": "error",
994
+ "@sarj/require-use-server-in-actions-file": "error",
995
+ "@sarj/source-coupled-test": "error",
992
996
  "@sarj/no-positional-tuple-return": "error",
993
997
  "@sarj/no-restated-comment": "error",
994
998
  "@sarj/no-restated-jsdoc": "error",
@@ -1004,7 +1008,7 @@ export function createConfig(options = {}) {
1004
1008
  "@sarj/prefer-whole-object-assertion": "error",
1005
1009
  "@sarj/duplicate-test-body": "error",
1006
1010
  "@sarj/test-loops-over-literal-cases": "error",
1007
- "@sarj/test-phase-label-comment": "warn",
1011
+ "@sarj/test-phase-label-comment": "error",
1008
1012
  // Both architectural rules stay enabled in the shared baseline. The
1009
1013
  // fetch rule ships conservative client/service defaults; consumers can
1010
1014
  // replace its `allow` list. The storage rule is intentionally inert until
@@ -18,7 +18,7 @@
18
18
  "peers": {
19
19
  "@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
20
20
  "@eslint/compat": "2.1.0",
21
- "@sarj/eslint-plugin": "15.12.1",
21
+ "@sarj/eslint-plugin": "15.13.0",
22
22
  "eslint": "10.8.1",
23
23
  "eslint-plugin-better-tailwindcss": "4.7.0",
24
24
  "eslint-plugin-perfectionist": "5.10.1",